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

Adds verification key for Wasm module #177

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

asraa
Copy link

@asraa asraa commented Jul 2, 2021

DRAFT: I think the argument should be a VerificationOptions struct containing possibly more keys, a verification type, all/none specification.

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

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

I think the hardcoded key should stay (and take a priority if used), since for binary authorization we want to make sure that if Envoy is compiled with a given key, then only Wasm modules signed with that key could be loaded and nothing else (even if provided in configuration). Yes, this is "I'm paranoid" feature :)

static const auto ed25519_pubkey = hex2pubkey<32>(PROXY_WASM_VERIFY_WITH_ED25519_PUBKEY);
char pubkey_char[65];
strcpy(pubkey_char, pubkey.c_str());
static const auto ed25519_pubkey = hex2pubkey<32>(pubkey_char);
Copy link
Member

Choose a reason for hiding this comment

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

This is static variable, so the first key used would persist forever and it would be used for all verifications, leading to false negatives.

@asraa
Copy link
Author

asraa commented Aug 12, 2021

Added some tests now for build time key precedence and no key present verification

@asraa
Copy link
Author

asraa commented Aug 12, 2021

Oh one quick comment I just remembered: should the pubkey inputs be validated at all? Or should we trust these relatively because of it's a configuration value that's likely valid

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

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

Could you rebase it on top of master, fix the failing tests and format errors?

@@ -88,3 +88,4 @@ jobs:
- name: Test (signed Wasm module)
run: |
bazel test --define runtime=${{ matrix.runtime }} --per_file_copt=//...@-DPROXY_WASM_VERIFY_WITH_ED25519_PUBKEY=\"$(xxd -p -c 256 test/test_data/signature_key1.pub | cut -b9-)\" //test:signature_util_test

Copy link
Member

Choose a reason for hiding this comment

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

Style: unnecesary change / newline.

@@ -345,8 +345,10 @@ using WasmHandleCloneFactory =
std::function<std::shared_ptr<WasmHandleBase>(std::shared_ptr<WasmHandleBase> wasm)>;

// Returns nullptr on failure (i.e. initialization of the VM fails).
// TODO: Consider a VerificationOptions struct rather than a single pubkey.
Copy link
Member

Choose a reason for hiding this comment

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

s/TODO/TODO(asraa)/

@@ -27,7 +27,7 @@ class SignatureUtil {
* @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);
static bool verifySignature(std::string_view bytecode, const std::string pubkey, std::string &message);
Copy link
Member

Choose a reason for hiding this comment

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

Style: clang-format warning (line too long).

std::shared_ptr<WasmHandleBase>
createWasm(std::string vm_key, std::string code, std::shared_ptr<PluginBase> plugin,
createWasm(std::string vm_key, std::string code, std::string pubkey,
std::shared_ptr<PluginBase> plugin,
Copy link
Member

Choose a reason for hiding this comment

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

Style: clang-format warning (weird indent).

@@ -463,6 +463,7 @@ WasmForeignFunction WasmBase::getForeignFunction(std::string_view function_name)
}

std::shared_ptr<WasmHandleBase> createWasm(std::string vm_key, std::string code,
std::string pubkey,
Copy link
Member

Choose a reason for hiding this comment

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

Style: clang-format warning (should be in the previous line).

@@ -249,9 +249,9 @@ bool WasmBase::load(const std::string &code, bool allow_precompiled) {
return true;
}

// Verify signature.
// Verify signature if a pubkey is present.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Verify signature if a pubkey is present.
// Verify signature if a public key is present (embedded at build-time or provided via pubkey).

@@ -24,36 +24,72 @@

namespace proxy_wasm {

TEST(TestSignatureUtil, GoodSignature) {
std::string BytesToHex(std::vector<uint8_t> bytes) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
std::string BytesToHex(std::vector<uint8_t> bytes) {
static std::string bytesToHex(std::vector<uint8_t> bytes) {

return result;
}

static std::string publickey(std::string filename) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
static std::string publickey(std::string filename) {
static std::string publicKey(std::string filename) {

if (!pubkey.empty()) {
char pubkey_char[65];
strcpy(pubkey_char, pubkey.c_str());
return hex2pubkey<32>(pubkey_char);
Copy link
Member

Choose a reason for hiding this comment

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

hex2pubkey is a constexpr template written to decode hex literal at the build-time with zero-cost at runtime.

But if you have to copy all the bytes to use it, then it kind of misses the point, and it would be better to add hexstr2pubkey function that can decode it in a single pass (basically, a runtime equivalent of hex2pubkey).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants