oasisprotocol / sapphire-paratime

Oasis Sapphire - the confidential EVM-compatible ParaTime for the Oasis Network
https://oasisprotocol.org/sapphire
Apache License 2.0
39 stars 27 forks source link

calldata public key verification work in client #412

Open CedarMist opened 2 months ago

netlify[bot] commented 2 months ago

Deploy Preview for oasisprotocol-sapphire-paratime canceled.

Name Link
Latest commit ef0dcbc5542f21f2dfa7e2208d66683511657957
Latest deploy log https://app.netlify.com/sites/oasisprotocol-sapphire-paratime/deploys/671d406a16a125000811342c
HarryR commented 1 month ago

@matevz @kostko

Re: calldata public key verification in clients

To prevent RPC server MITM.

This applies to all clients where you want to establish secure connection between a client app & Sapphire, without having to run your own RPC node.

Signature is in the form of Sign(sk, (key || checksum || runtime id || key pair id || epoch || expiration epoch)), meaning we need to have checksum, runtime id and key pair id.

There are a couple of approaches which were considered:

  1. Hard-code Keymanager public key in client, to verify result of oasis_callDataPublicKey and core.CallDataPublicKey
  2. Build light client
  3. Have smart contract on-chain generate long-term key pair, use together with core.CallDataPublicKey to establish trust
  4. Serve key manager info from a HTTPS URL

Approach 1

How frequently would checksum, sk and key pair id need to change?

If sk is rotated, or checksum changes or key pair id changes - client will reject new signed CallDataPublicKeys

This would break previously deployed dApps if key is rotated.

Approach 2

This would add significant weight to every client, probably megabytes or more, and may take a fair amount of time to sync every time you start a dApp.

This would be difficult in environments where outbound connections are firewalled etc.

Consensus upgrades could break previously deployed dApps if protocol or light client becomes incompatible.

Approach 3

If key manager signing key changes the smart contract will continue signing stuff without interruption, so the key manager key can rotate etc.

But, the root of trust is a key inside a smart contract on Sapphire which is embedded into the client library.

This would require compromise of Sapphire compute node to extract the key before a MITM attack can be made.

Approach 4

Requires an outbound HTTPS connection to a domain to retrieve the key information. This would be per-chain? (e.g. Localnet, Testnet, Mainnet, Pontus-[Local/Test/Main/Dev].

Using a static URL to retrieve the key depending on Chain ID is particularly difficult with Localnet, which may not be at localhost:8545 (e.g. if it's deployed with docker swarm).

lukaw3d commented 1 month ago

Potential approach 5:

If MITM returns a fake public key and reads and submits your transaction: invalid encryption envelope If MITM returns a fake public key and rewrites your transaction using real public key: invalid signature

i think

CedarMist commented 1 month ago

Yup, if the RPC does MITM your tx will either fail with decryption error or will be signed by a different key (so different tx hash).

This approach requires you to spend gas though, every time an app is loaded. Which will require signing from a gas paying account

kostko commented 1 month ago

I assume it could also be a combination of things that one can use, as long as the app developer can decide what tradeoff to use.

A note about light clients: