From e4042ae4da7c9c7ee37d3fce99db39685364b81b Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Fri, 14 May 2021 21:27:07 -0700 Subject: [PATCH] Add support for loading and verifying signed Wasm modules. (#147) Signed-off-by: Piotr Sikora --- .github/workflows/cpp.yml | 3 + bazel/cargo/BUILD.bazel | 20 +++ bazel/cargo/Cargo.raze.lock | 87 +++++++++++++ bazel/cargo/Cargo.toml | 4 + bazel/cargo/crates.bzl | 99 +++++++++++++++ .../cargo/remote/BUILD.ansi_term-0.11.0.bazel | 66 ++++++++++ .../cargo/remote/BUILD.byteorder-1.4.3.bazel | 2 + bazel/cargo/remote/BUILD.clap-2.33.3.bazel | 93 ++++++++++++++ .../remote/BUILD.ed25519-compact-0.1.9.bazel | 58 +++++++++ .../remote/BUILD.hmac-sha512-0.1.9.bazel | 55 ++++++++ .../remote/BUILD.parity-wasm-0.42.2.bazel | 71 +++++++++++ bazel/cargo/remote/BUILD.strsim-0.8.0.bazel | 57 +++++++++ .../cargo/remote/BUILD.textwrap-0.11.0.bazel | 62 +++++++++ .../remote/BUILD.unicode-width-0.1.8.bazel | 54 ++++++++ bazel/cargo/remote/BUILD.vec_map-0.8.2.bazel | 53 ++++++++ bazel/cargo/remote/BUILD.wasmsign-0.1.2.bazel | 91 ++++++++++++++ bazel/wasm.bzl | 25 ++-- include/proxy-wasm/signature_util.h | 33 +++++ src/signature_util.cc | 119 ++++++++++++++++++ src/wasm.cc | 10 ++ test/BUILD | 18 +++ test/signature_util_test.cc | 60 +++++++++ test/test_data/BUILD | 18 +++ test/test_data/signature_key1.key | Bin 0 -> 68 bytes test/test_data/signature_key1.pub | Bin 0 -> 36 bytes test/test_data/signature_key2.key | Bin 0 -> 68 bytes test/test_data/signature_key2.pub | Bin 0 -> 36 bytes 27 files changed, 1151 insertions(+), 7 deletions(-) create mode 100644 bazel/cargo/remote/BUILD.ansi_term-0.11.0.bazel create mode 100644 bazel/cargo/remote/BUILD.clap-2.33.3.bazel create mode 100644 bazel/cargo/remote/BUILD.ed25519-compact-0.1.9.bazel create mode 100644 bazel/cargo/remote/BUILD.hmac-sha512-0.1.9.bazel create mode 100644 bazel/cargo/remote/BUILD.parity-wasm-0.42.2.bazel create mode 100644 bazel/cargo/remote/BUILD.strsim-0.8.0.bazel create mode 100644 bazel/cargo/remote/BUILD.textwrap-0.11.0.bazel create mode 100644 bazel/cargo/remote/BUILD.unicode-width-0.1.8.bazel create mode 100644 bazel/cargo/remote/BUILD.vec_map-0.8.2.bazel create mode 100644 bazel/cargo/remote/BUILD.wasmsign-0.1.2.bazel create mode 100644 include/proxy-wasm/signature_util.h create mode 100644 src/signature_util.cc create mode 100644 test/signature_util_test.cc create mode 100644 test/test_data/signature_key1.key create mode 100644 test/test_data/signature_key1.pub create mode 100644 test/test_data/signature_key2.key create mode 100644 test/test_data/signature_key2.pub diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index ab27b279..4bfc8619 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -75,3 +75,6 @@ jobs: run: | bazel test --define runtime=${{ matrix.runtime }} //... + - name: Test (signed Wasm module) + run: | + bazel test --define runtime=${{ matrix.runtime }} --cxxopt=-DPROXY_WASM_VERIFY_WITH_ED25519_PUBKEY=\"$(xxd -p -c 256 test/test_data/signature_key1.pub | cut -b9-)\" //test:signature_util_test diff --git a/bazel/cargo/BUILD.bazel b/bazel/cargo/BUILD.bazel index b52a8feb..1e5fb688 100644 --- a/bazel/cargo/BUILD.bazel +++ b/bazel/cargo/BUILD.bazel @@ -39,6 +39,26 @@ alias( ], ) +alias( + name = "wasmsign", + actual = "@proxy_wasm_cpp_host__wasmsign__0_1_2//:wasmsign", + tags = [ + "cargo-raze", + "manual", + ], +) + +alias( + # Extra aliased target, from raze configuration + # N.B.: The exact form of this is subject to change. + name = "cargo_bin_wasmsign", + actual = "@proxy_wasm_cpp_host__wasmsign__0_1_2//:cargo_bin_wasmsign", + tags = [ + "cargo-raze", + "manual", + ], +) + alias( name = "wasmtime", actual = "@proxy_wasm_cpp_host__wasmtime__0_26_0//:wasmtime", diff --git a/bazel/cargo/Cargo.raze.lock b/bazel/cargo/Cargo.raze.lock index 03711991..a4c2ece9 100644 --- a/bazel/cargo/Cargo.raze.lock +++ b/bazel/cargo/Cargo.raze.lock @@ -33,6 +33,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.40" @@ -104,6 +113,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "cpp_demangle" version = "0.3.2" @@ -219,6 +243,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ed25519-compact" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf396058cc7285b342f9a10ed7a377f088942396c46c4c9a7eb4f0782cb1171" +dependencies = [ + "getrandom", +] + [[package]] name = "either" version = "1.6.1" @@ -293,6 +326,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hmac-sha512" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383" + [[package]] name = "humantime" version = "2.1.0" @@ -402,6 +441,12 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +[[package]] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + [[package]] name = "paste" version = "1.0.5" @@ -566,6 +611,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "syn" version = "1.0.72" @@ -592,6 +643,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.24" @@ -612,12 +672,24 @@ dependencies = [ "syn", ] +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -630,6 +702,20 @@ version = "0.77.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35c86d22e720a07d954ebbed772d01180501afe7d03d464f413bb5f8914a8d6" +[[package]] +name = "wasmsign" +version = "0.1.2" +source = "git+https://github.com/jedisct1/wasmsign#fa4d5598f778390df09be94232972b5b865a56b8" +dependencies = [ + "anyhow", + "byteorder", + "clap", + "ed25519-compact", + "hmac-sha512", + "parity-wasm", + "thiserror", +] + [[package]] name = "wasmtime" version = "0.26.0" @@ -667,6 +753,7 @@ dependencies = [ "anyhow", "env_logger", "once_cell", + "wasmsign", "wasmtime", "wasmtime-c-api-macros", ] diff --git a/bazel/cargo/Cargo.toml b/bazel/cargo/Cargo.toml index 52b2a361..1b7bdb13 100644 --- a/bazel/cargo/Cargo.toml +++ b/bazel/cargo/Cargo.toml @@ -12,6 +12,7 @@ anyhow = "1.0" once_cell = "1.3" wasmtime = {version = "0.26.0", default-features = false} wasmtime-c-api-macros = {git = "https://github.com/bytecodealliance/wasmtime", tag = "v0.26.0", path = "crates/c-api/macros"} +wasmsign = {git = "https://github.com/jedisct1/wasmsign", revision = "fa4d5598f778390df09be94232972b5b865a56b8"} [package.metadata.raze] rust_rules_workspace_name = "rules_rust" @@ -19,3 +20,6 @@ gen_workspace_prefix = "proxy_wasm_cpp_host" genmode = "Remote" package_aliases_dir = "." workspace_path = "//bazel/cargo" + +[package.metadata.raze.crates.wasmsign.'*'] +extra_aliased_targets = ["cargo_bin_wasmsign"] diff --git a/bazel/cargo/crates.bzl b/bazel/cargo/crates.bzl index 7637d439..c6b0c192 100644 --- a/bazel/cargo/crates.bzl +++ b/bazel/cargo/crates.bzl @@ -51,6 +51,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.aho-corasick-0.7.18.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__ansi_term__0_11_0", + url = "https://crates.io/api/v1/crates/ansi_term/0.11.0/download", + type = "tar.gz", + sha256 = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b", + strip_prefix = "ansi_term-0.11.0", + build_file = Label("//bazel/cargo/remote:BUILD.ansi_term-0.11.0.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__anyhow__1_0_40", @@ -141,6 +151,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.cfg-if-1.0.0.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__clap__2_33_3", + url = "https://crates.io/api/v1/crates/clap/2.33.3/download", + type = "tar.gz", + sha256 = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002", + strip_prefix = "clap-2.33.3", + build_file = Label("//bazel/cargo/remote:BUILD.clap-2.33.3.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__cpp_demangle__0_3_2", @@ -241,6 +261,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.crc32fast-1.2.1.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__ed25519_compact__0_1_9", + url = "https://crates.io/api/v1/crates/ed25519-compact/0.1.9/download", + type = "tar.gz", + sha256 = "aaf396058cc7285b342f9a10ed7a377f088942396c46c4c9a7eb4f0782cb1171", + strip_prefix = "ed25519-compact-0.1.9", + build_file = Label("//bazel/cargo/remote:BUILD.ed25519-compact-0.1.9.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__either__1_6_1", @@ -331,6 +361,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.hermit-abi-0.1.18.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__hmac_sha512__0_1_9", + url = "https://crates.io/api/v1/crates/hmac-sha512/0.1.9/download", + type = "tar.gz", + sha256 = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383", + strip_prefix = "hmac-sha512-0.1.9", + build_file = Label("//bazel/cargo/remote:BUILD.hmac-sha512-0.1.9.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__humantime__2_1_0", @@ -471,6 +511,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.once_cell-1.7.2.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__parity_wasm__0_42_2", + url = "https://crates.io/api/v1/crates/parity-wasm/0.42.2/download", + type = "tar.gz", + sha256 = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92", + strip_prefix = "parity-wasm-0.42.2", + build_file = Label("//bazel/cargo/remote:BUILD.parity-wasm-0.42.2.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__paste__1_0_5", @@ -661,6 +711,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.stable_deref_trait-1.2.0.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__strsim__0_8_0", + url = "https://crates.io/api/v1/crates/strsim/0.8.0/download", + type = "tar.gz", + sha256 = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a", + strip_prefix = "strsim-0.8.0", + build_file = Label("//bazel/cargo/remote:BUILD.strsim-0.8.0.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__syn__1_0_72", @@ -691,6 +751,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.termcolor-1.1.2.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__textwrap__0_11_0", + url = "https://crates.io/api/v1/crates/textwrap/0.11.0/download", + type = "tar.gz", + sha256 = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060", + strip_prefix = "textwrap-0.11.0", + build_file = Label("//bazel/cargo/remote:BUILD.textwrap-0.11.0.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__thiserror__1_0_24", @@ -711,6 +781,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.thiserror-impl-1.0.24.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__unicode_width__0_1_8", + url = "https://crates.io/api/v1/crates/unicode-width/0.1.8/download", + type = "tar.gz", + sha256 = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3", + strip_prefix = "unicode-width-0.1.8", + build_file = Label("//bazel/cargo/remote:BUILD.unicode-width-0.1.8.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__unicode_xid__0_2_2", @@ -721,6 +801,16 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.unicode-xid-0.2.2.bazel"), ) + maybe( + http_archive, + name = "proxy_wasm_cpp_host__vec_map__0_8_2", + url = "https://crates.io/api/v1/crates/vec_map/0.8.2/download", + type = "tar.gz", + sha256 = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191", + strip_prefix = "vec_map-0.8.2", + build_file = Label("//bazel/cargo/remote:BUILD.vec_map-0.8.2.bazel"), + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__wasi__0_10_2_wasi_snapshot_preview1", @@ -741,6 +831,15 @@ def proxy_wasm_cpp_host_fetch_remote_crates(): build_file = Label("//bazel/cargo/remote:BUILD.wasmparser-0.77.0.bazel"), ) + maybe( + new_git_repository, + name = "proxy_wasm_cpp_host__wasmsign__0_1_2", + remote = "https://github.com/jedisct1/wasmsign", + commit = "fa4d5598f778390df09be94232972b5b865a56b8", + build_file = Label("//bazel/cargo/remote:BUILD.wasmsign-0.1.2.bazel"), + init_submodules = True, + ) + maybe( http_archive, name = "proxy_wasm_cpp_host__wasmtime__0_26_0", diff --git a/bazel/cargo/remote/BUILD.ansi_term-0.11.0.bazel b/bazel/cargo/remote/BUILD.ansi_term-0.11.0.bazel new file mode 100644 index 00000000..a05ec6e2 --- /dev/null +++ b/bazel/cargo/remote/BUILD.ansi_term-0.11.0.bazel @@ -0,0 +1,66 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT" +]) + +# Generated Targets + +# Unsupported target "colours" with type "example" omitted + +rust_library( + name = "ansi_term", + srcs = glob(["**/*.rs"]), + aliases = { + }, + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.11.0", + # buildifier: leave-alone + deps = [ + ] + selects.with_or({ + # cfg(target_os = "windows") + ( + "@rules_rust//rust/platform:i686-pc-windows-msvc", + "@rules_rust//rust/platform:x86_64-pc-windows-msvc", + ): [ + "@proxy_wasm_cpp_host__winapi__0_3_9//:winapi", + ], + "//conditions:default": [], + }), +) diff --git a/bazel/cargo/remote/BUILD.byteorder-1.4.3.bazel b/bazel/cargo/remote/BUILD.byteorder-1.4.3.bazel index af0e2cc7..b998b1fb 100644 --- a/bazel/cargo/remote/BUILD.byteorder-1.4.3.bazel +++ b/bazel/cargo/remote/BUILD.byteorder-1.4.3.bazel @@ -36,6 +36,8 @@ rust_library( name = "byteorder", srcs = glob(["**/*.rs"]), crate_features = [ + "default", + "std", ], crate_root = "src/lib.rs", crate_type = "lib", diff --git a/bazel/cargo/remote/BUILD.clap-2.33.3.bazel b/bazel/cargo/remote/BUILD.clap-2.33.3.bazel new file mode 100644 index 00000000..2211f357 --- /dev/null +++ b/bazel/cargo/remote/BUILD.clap-2.33.3.bazel @@ -0,0 +1,93 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT" +]) + +# Generated Targets + +rust_library( + name = "clap", + srcs = glob(["**/*.rs"]), + aliases = { + }, + crate_features = [ + "ansi_term", + "atty", + "color", + "default", + "strsim", + "suggestions", + "vec_map", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "2.33.3", + # buildifier: leave-alone + deps = [ + "@proxy_wasm_cpp_host__atty__0_2_14//:atty", + "@proxy_wasm_cpp_host__bitflags__1_2_1//:bitflags", + "@proxy_wasm_cpp_host__strsim__0_8_0//:strsim", + "@proxy_wasm_cpp_host__textwrap__0_11_0//:textwrap", + "@proxy_wasm_cpp_host__unicode_width__0_1_8//:unicode_width", + "@proxy_wasm_cpp_host__vec_map__0_8_2//:vec_map", + ] + selects.with_or({ + # cfg(not(windows)) + ( + "@rules_rust//rust/platform:aarch64-apple-darwin", + "@rules_rust//rust/platform:aarch64-apple-ios", + "@rules_rust//rust/platform:aarch64-linux-android", + "@rules_rust//rust/platform:aarch64-unknown-linux-gnu", + "@rules_rust//rust/platform:arm-unknown-linux-gnueabi", + "@rules_rust//rust/platform:i686-apple-darwin", + "@rules_rust//rust/platform:i686-linux-android", + "@rules_rust//rust/platform:i686-unknown-freebsd", + "@rules_rust//rust/platform:i686-unknown-linux-gnu", + "@rules_rust//rust/platform:powerpc-unknown-linux-gnu", + "@rules_rust//rust/platform:s390x-unknown-linux-gnu", + "@rules_rust//rust/platform:wasm32-unknown-unknown", + "@rules_rust//rust/platform:wasm32-wasi", + "@rules_rust//rust/platform:x86_64-apple-darwin", + "@rules_rust//rust/platform:x86_64-apple-ios", + "@rules_rust//rust/platform:x86_64-linux-android", + "@rules_rust//rust/platform:x86_64-unknown-freebsd", + "@rules_rust//rust/platform:x86_64-unknown-linux-gnu", + ): [ + "@proxy_wasm_cpp_host__ansi_term__0_11_0//:ansi_term", + ], + "//conditions:default": [], + }), +) diff --git a/bazel/cargo/remote/BUILD.ed25519-compact-0.1.9.bazel b/bazel/cargo/remote/BUILD.ed25519-compact-0.1.9.bazel new file mode 100644 index 00000000..166ee592 --- /dev/null +++ b/bazel/cargo/remote/BUILD.ed25519-compact-0.1.9.bazel @@ -0,0 +1,58 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # ISC from expression "ISC" +]) + +# Generated Targets + +rust_library( + name = "ed25519_compact", + srcs = glob(["**/*.rs"]), + crate_features = [ + "default", + "getrandom", + "random", + "std", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.1.9", + # buildifier: leave-alone + deps = [ + "@proxy_wasm_cpp_host__getrandom__0_2_2//:getrandom", + ], +) diff --git a/bazel/cargo/remote/BUILD.hmac-sha512-0.1.9.bazel b/bazel/cargo/remote/BUILD.hmac-sha512-0.1.9.bazel new file mode 100644 index 00000000..cc0ccb2e --- /dev/null +++ b/bazel/cargo/remote/BUILD.hmac-sha512-0.1.9.bazel @@ -0,0 +1,55 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # ISC from expression "ISC" +]) + +# Generated Targets + +rust_library( + name = "hmac_sha512", + srcs = glob(["**/*.rs"]), + crate_features = [ + "default", + "sha384", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.1.9", + # buildifier: leave-alone + deps = [ + ], +) diff --git a/bazel/cargo/remote/BUILD.parity-wasm-0.42.2.bazel b/bazel/cargo/remote/BUILD.parity-wasm-0.42.2.bazel new file mode 100644 index 00000000..cdce833c --- /dev/null +++ b/bazel/cargo/remote/BUILD.parity-wasm-0.42.2.bazel @@ -0,0 +1,71 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets + +# Unsupported target "bench-decoder" with type "example" omitted + +# Unsupported target "build" with type "example" omitted + +# Unsupported target "data" with type "example" omitted + +# Unsupported target "exports" with type "example" omitted + +# Unsupported target "info" with type "example" omitted + +# Unsupported target "inject" with type "example" omitted + +# Unsupported target "roundtrip" with type "example" omitted + +# Unsupported target "show" with type "example" omitted + +rust_library( + name = "parity_wasm", + srcs = glob(["**/*.rs"]), + crate_features = [ + "default", + "std", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.42.2", + # buildifier: leave-alone + deps = [ + ], +) diff --git a/bazel/cargo/remote/BUILD.strsim-0.8.0.bazel b/bazel/cargo/remote/BUILD.strsim-0.8.0.bazel new file mode 100644 index 00000000..131b093f --- /dev/null +++ b/bazel/cargo/remote/BUILD.strsim-0.8.0.bazel @@ -0,0 +1,57 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT" +]) + +# Generated Targets + +# Unsupported target "benches" with type "bench" omitted + +rust_library( + name = "strsim", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.8.0", + # buildifier: leave-alone + deps = [ + ], +) + +# Unsupported target "lib" with type "test" omitted diff --git a/bazel/cargo/remote/BUILD.textwrap-0.11.0.bazel b/bazel/cargo/remote/BUILD.textwrap-0.11.0.bazel new file mode 100644 index 00000000..4fd9aab3 --- /dev/null +++ b/bazel/cargo/remote/BUILD.textwrap-0.11.0.bazel @@ -0,0 +1,62 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT" +]) + +# Generated Targets + +# Unsupported target "linear" with type "bench" omitted + +# Unsupported target "layout" with type "example" omitted + +# Unsupported target "termwidth" with type "example" omitted + +rust_library( + name = "textwrap", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.11.0", + # buildifier: leave-alone + deps = [ + "@proxy_wasm_cpp_host__unicode_width__0_1_8//:unicode_width", + ], +) + +# Unsupported target "version-numbers" with type "test" omitted diff --git a/bazel/cargo/remote/BUILD.unicode-width-0.1.8.bazel b/bazel/cargo/remote/BUILD.unicode-width-0.1.8.bazel new file mode 100644 index 00000000..7cc93798 --- /dev/null +++ b/bazel/cargo/remote/BUILD.unicode-width-0.1.8.bazel @@ -0,0 +1,54 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets + +rust_library( + name = "unicode_width", + srcs = glob(["**/*.rs"]), + crate_features = [ + "default", + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.1.8", + # buildifier: leave-alone + deps = [ + ], +) diff --git a/bazel/cargo/remote/BUILD.vec_map-0.8.2.bazel b/bazel/cargo/remote/BUILD.vec_map-0.8.2.bazel new file mode 100644 index 00000000..2a6a4729 --- /dev/null +++ b/bazel/cargo/remote/BUILD.vec_map-0.8.2.bazel @@ -0,0 +1,53 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "notice", # MIT from expression "MIT OR Apache-2.0" +]) + +# Generated Targets + +rust_library( + name = "vec_map", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2015", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.8.2", + # buildifier: leave-alone + deps = [ + ], +) diff --git a/bazel/cargo/remote/BUILD.wasmsign-0.1.2.bazel b/bazel/cargo/remote/BUILD.wasmsign-0.1.2.bazel new file mode 100644 index 00000000..7d2a94dc --- /dev/null +++ b/bazel/cargo/remote/BUILD.wasmsign-0.1.2.bazel @@ -0,0 +1,91 @@ +""" +@generated +cargo-raze crate build file. + +DO NOT EDIT! Replaced on runs of cargo-raze +""" + +# buildifier: disable=load +load("@bazel_skylib//lib:selects.bzl", "selects") + +# buildifier: disable=load +load( + "@rules_rust//rust:rust.bzl", + "rust_binary", + "rust_library", + "rust_test", +) + +package(default_visibility = [ + # Public for visibility by "@raze__crate__version//" targets. + # + # Prefer access through "//bazel/cargo", which limits external + # visibility to explicit Cargo.toml dependencies. + "//visibility:public", +]) + +licenses([ + "restricted", # no license +]) + +# Generated Targets + +rust_binary( + # Prefix bin name to disambiguate from (probable) collision with lib name + # N.B.: The exact form of this is subject to change. + name = "cargo_bin_wasmsign", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/bin/wasmsign.rs", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.1.2", + # buildifier: leave-alone + deps = [ + ":wasmsign", + "@proxy_wasm_cpp_host__anyhow__1_0_40//:anyhow", + "@proxy_wasm_cpp_host__byteorder__1_4_3//:byteorder", + "@proxy_wasm_cpp_host__clap__2_33_3//:clap", + "@proxy_wasm_cpp_host__ed25519_compact__0_1_9//:ed25519_compact", + "@proxy_wasm_cpp_host__hmac_sha512__0_1_9//:hmac_sha512", + "@proxy_wasm_cpp_host__parity_wasm__0_42_2//:parity_wasm", + "@proxy_wasm_cpp_host__thiserror__1_0_24//:thiserror", + ], +) + +rust_library( + name = "wasmsign", + srcs = glob(["**/*.rs"]), + crate_features = [ + ], + crate_root = "src/lib.rs", + crate_type = "lib", + data = [], + edition = "2018", + rustc_flags = [ + "--cap-lints=allow", + ], + tags = [ + "cargo-raze", + "manual", + ], + version = "0.1.2", + # buildifier: leave-alone + deps = [ + "@proxy_wasm_cpp_host__anyhow__1_0_40//:anyhow", + "@proxy_wasm_cpp_host__byteorder__1_4_3//:byteorder", + "@proxy_wasm_cpp_host__clap__2_33_3//:clap", + "@proxy_wasm_cpp_host__ed25519_compact__0_1_9//:ed25519_compact", + "@proxy_wasm_cpp_host__hmac_sha512__0_1_9//:hmac_sha512", + "@proxy_wasm_cpp_host__parity_wasm__0_42_2//:parity_wasm", + "@proxy_wasm_cpp_host__thiserror__1_0_24//:thiserror", + ], +) diff --git a/bazel/wasm.bzl b/bazel/wasm.bzl index aba74aeb..8bc3351b 100644 --- a/bazel/wasm.bzl +++ b/bazel/wasm.bzl @@ -42,18 +42,28 @@ wasi_rust_transition = transition( def _wasm_binary_impl(ctx): out = ctx.actions.declare_file(ctx.label.name) - ctx.actions.run( - executable = "cp", - arguments = [ctx.files.binary[0].path, out.path], - outputs = [out], - inputs = ctx.files.binary, - ) + if ctx.attr.signing_key: + ctx.actions.run( + executable = ctx.executable._wasmsign_tool, + arguments = ["--sign", "--use-custom-section", "--sk-path", ctx.files.signing_key[0].path, "--pk-path", ctx.files.signing_key[1].path, "--input", ctx.files.binary[0].path, "--output", out.path], + outputs = [out], + inputs = ctx.files.binary + ctx.files.signing_key, + ) + else: + ctx.actions.run( + executable = "cp", + arguments = [ctx.files.binary[0].path, out.path], + outputs = [out], + inputs = ctx.files.binary, + ) return [DefaultInfo(files = depset([out]), runfiles = ctx.runfiles([out]))] def _wasm_attrs(transition): return { "binary": attr.label(mandatory = True, cfg = transition), + "signing_key": attr.label_list(allow_files = True), + "_wasmsign_tool": attr.label(default = "//bazel/cargo:cargo_bin_wasmsign", executable = True, cfg = "exec"), "_whitelist_function_transition": attr.label(default = "@bazel_tools//tools/whitelists/function_transition_whitelist"), } @@ -67,7 +77,7 @@ wasi_rust_binary_rule = rule( attrs = _wasm_attrs(wasi_rust_transition), ) -def wasm_rust_binary(name, tags = [], wasi = False, **kwargs): +def wasm_rust_binary(name, tags = [], wasi = False, signing_key = [], **kwargs): wasm_name = "_wasm_" + name.replace(".", "_") kwargs.setdefault("visibility", ["//visibility:public"]) @@ -87,5 +97,6 @@ def wasm_rust_binary(name, tags = [], wasi = False, **kwargs): bin_rule( name = name, binary = ":" + wasm_name, + signing_key = signing_key, tags = tags + ["manual"], ) diff --git a/include/proxy-wasm/signature_util.h b/include/proxy-wasm/signature_util.h new file mode 100644 index 00000000..68579dcd --- /dev/null +++ b/include/proxy-wasm/signature_util.h @@ -0,0 +1,33 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +namespace proxy_wasm { + +// Utility functions to verify Wasm signatures. +class SignatureUtil { +public: + /** + * verifySignature validates Wasm signature. + * @param bytecode is the source bytecode. + * @param message is the reference to store the message (success or error). + * @return indicates whether the bytecode has a valid Wasm signature. + */ + static bool verifySignature(std::string_view bytecode, std::string &message); +}; + +} // namespace proxy_wasm diff --git a/src/signature_util.cc b/src/signature_util.cc new file mode 100644 index 00000000..71b1341c --- /dev/null +++ b/src/signature_util.cc @@ -0,0 +1,119 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "include/proxy-wasm/signature_util.h" + +#include +#include + +#include +#include + +#include "include/proxy-wasm/bytecode_util.h" + +namespace { + +#ifdef PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY + +static uint8_t hex2dec(const unsigned char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } else { + throw std::logic_error{"invalid hex character"}; + } +} + +template constexpr std::array hex2pubkey(const char (&hex)[2 * N + 1]) { + std::array pubkey; + for (size_t i = 0; i < pubkey.size(); i++) { + pubkey[i] = hex2dec(hex[2 * i]) << 4 | hex2dec(hex[2 * i + 1]); + } + return pubkey; +} + +#endif + +} // namespace + +namespace proxy_wasm { + +bool SignatureUtil::verifySignature(std::string_view bytecode, std::string &message) { + +#ifdef PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY + + /* + * Ed25519 signature generated using https://github.com/jedisct1/wasmsign + */ + + std::string_view payload; + if (!BytecodeUtil::getCustomSection(bytecode, "signature_wasmsign", payload)) { + message = "Failed to parse corrupted Wasm module"; + return false; + } + + if (payload.empty()) { + message = "Custom Section \"signature_wasmsign\" not found"; + return false; + } + + if (bytecode.data() + bytecode.size() != payload.data() + payload.size()) { + message = "Custom Section \"signature_wasmsign\" not at the end of Wasm module"; + return false; + } + + if (payload.size() != 68) { + message = "Signature has a wrong size (want: 68, is: " + std::to_string(payload.size()) + ")"; + return false; + } + + uint32_t alg_id; + std::memcpy(&alg_id, payload.data(), sizeof(uint32_t)); + + if (alg_id != 2) { + message = "Signature has a wrong alg_id (want: 2, is: " + std::to_string(alg_id) + ")"; + return false; + } + + const auto *signature = reinterpret_cast(payload.data()) + sizeof(uint32_t); + + SHA512_CTX ctx; + SHA512_Init(&ctx); + SHA512_Update(&ctx, "WasmSignature", sizeof("WasmSignature") - 1); + const uint32_t ad_len = 0; + SHA512_Update(&ctx, &ad_len, sizeof(uint32_t)); + const size_t section_len = 3 + sizeof("signature_wasmsign") - 1 + 68; + SHA512_Update(&ctx, bytecode.data(), bytecode.size() - section_len); + uint8_t hash[SHA512_DIGEST_LENGTH]; + SHA512_Final(hash, &ctx); + + static const auto ed25519_pubkey = hex2pubkey<32>(PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY); + + if (!ED25519_verify(hash, sizeof(hash), signature, ed25519_pubkey.data())) { + message = "Signature mismatch"; + return false; + } + + message = "Wasm signature OK (Ed25519)"; + return true; + +#endif + + return true; +} + +} // namespace proxy_wasm diff --git a/src/wasm.cc b/src/wasm.cc index cf2010ff..a0f248f8 100644 --- a/src/wasm.cc +++ b/src/wasm.cc @@ -27,6 +27,7 @@ #include #include "include/proxy-wasm/bytecode_util.h" +#include "include/proxy-wasm/signature_util.h" #include "include/proxy-wasm/vm_id_handle.h" #include "src/third_party/base64.h" @@ -250,6 +251,15 @@ bool WasmBase::load(const std::string &code, bool allow_precompiled) { return true; } + // Verify signature. + std::string message; + if (!SignatureUtil::verifySignature(code, message)) { + fail(FailState::UnableToInitializeCode, message); + return false; + } else { + wasm_vm_->integration()->trace(message); + } + // Get ABI version from the module. if (!BytecodeUtil::getAbiVersion(code, abi_version_)) { fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); diff --git a/test/BUILD b/test/BUILD index ec45c17b..d41c657a 100644 --- a/test/BUILD +++ b/test/BUILD @@ -26,6 +26,24 @@ cc_test( ], ) +cc_test( + name = "signature_util_test", + srcs = ["signature_util_test.cc"], + data = [ + "//test/test_data:abi_export.signed.with.key1.wasm", + "//test/test_data:abi_export.signed.with.key2.wasm", + "//test/test_data:abi_export.wasm", + ], + # Test only when compiled to verify plugins. + tags = ["manual"], + deps = [ + ":utility_lib", + "//:lib", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "runtime_test", srcs = ["runtime_test.cc"], diff --git a/test/signature_util_test.cc b/test/signature_util_test.cc new file mode 100644 index 00000000..f4b2ae24 --- /dev/null +++ b/test/signature_util_test.cc @@ -0,0 +1,60 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "include/proxy-wasm/signature_util.h" + +#include +#include +#include + +#include "test/utility.h" + +#include "gtest/gtest.h" + +namespace proxy_wasm { + +TEST(TestSignatureUtil, GoodSignature) { +#ifndef PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY + FAIL() << "Built without a key for verifying signed Wasm modules."; +#endif + + const auto bytecode = readTestWasmFile("abi_export.signed.with.key1.wasm"); + std::string message; + EXPECT_TRUE(SignatureUtil::verifySignature(bytecode, message)); + EXPECT_EQ(message, "Wasm signature OK (Ed25519)"); +} + +TEST(TestSignatureUtil, BadSignature) { +#ifndef PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY + FAIL() << "Built without a key for verifying signed Wasm modules."; +#endif + + const auto bytecode = readTestWasmFile("abi_export.signed.with.key2.wasm"); + std::string message; + EXPECT_FALSE(SignatureUtil::verifySignature(bytecode, message)); + EXPECT_EQ(message, "Signature mismatch"); +} + +TEST(TestSignatureUtil, NoSignature) { +#ifndef PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY + FAIL() << "Built without a key for verifying signed Wasm modules."; +#endif + + const auto bytecode = readTestWasmFile("abi_export.wasm"); + std::string message; + EXPECT_FALSE(SignatureUtil::verifySignature(bytecode, message)); + EXPECT_EQ(message, "Custom Section \"signature_wasmsign\" not found"); +} + +} // namespace proxy_wasm diff --git a/test/test_data/BUILD b/test/test_data/BUILD index 3d99c103..571ca930 100644 --- a/test/test_data/BUILD +++ b/test/test_data/BUILD @@ -7,6 +7,24 @@ wasm_rust_binary( srcs = ["abi_export.rs"], ) +wasm_rust_binary( + name = "abi_export.signed.with.key1.wasm", + srcs = ["abi_export.rs"], + signing_key = [ + "signature_key1.key", + "signature_key1.pub", + ], +) + +wasm_rust_binary( + name = "abi_export.signed.with.key2.wasm", + srcs = ["abi_export.rs"], + signing_key = [ + "signature_key2.key", + "signature_key2.pub", + ], +) + wasm_rust_binary( name = "callback.wasm", srcs = ["callback.rs"], diff --git a/test/test_data/signature_key1.key b/test/test_data/signature_key1.key new file mode 100644 index 0000000000000000000000000000000000000000..c1a292b6a934dd518e6401114fc226f938f2eac0 GIT binary patch literal 68 zcmV-K0K5MJ0000A!l8mPC&;5789l96_4twE!i>E29FjkUuVyTKj#_*(`}>$Me literal 0 HcmV?d00001 diff --git a/test/test_data/signature_key1.pub b/test/test_data/signature_key1.pub new file mode 100644 index 0000000000000000000000000000000000000000..034a0de349cea573584a30a203b4ceb62c4e30aa GIT binary patch literal 36 scmZQ#U|=x*{X5oC*LY*igq9xmva2hTq3^01d|wr~m)} literal 0 HcmV?d00001 diff --git a/test/test_data/signature_key2.key b/test/test_data/signature_key2.key new file mode 100644 index 0000000000000000000000000000000000000000..8ba90fb90412d035099aaa13214c4a0785126e26 GIT binary patch literal 68 zcmV-K0K5MJ00023sBUg}JWO^_IY)xf=?4Ds?%7$P-gx4)s(-oFDVbGmeZ#tutM`kL ac