From 8548d7dcb6dde6d52bd410511cf73ff1afff923d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 19 Jan 2018 09:04:32 +0100 Subject: [PATCH] signer: documentation --- cmd/signer/README.md | 28 ++++++++-- cmd/signer/main.go | 19 ++++--- cmd/signer/pythonsigner.py | 4 +- cmd/signer/rules.md | 107 +++++++++++++++++++++++++++++++++++++ cmd/signer/sign_flow.png | Bin 0 -> 36397 bytes 5 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 cmd/signer/rules.md create mode 100644 cmd/signer/sign_flow.png diff --git a/cmd/signer/README.md b/cmd/signer/README.md index 9a09870dba..dad2f2bc04 100644 --- a/cmd/signer/README.md +++ b/cmd/signer/README.md @@ -35,6 +35,21 @@ Example: signer -keystore /my/keystore -chainid 4 ``` +## Security model + +The security model of the signer is as follows: + +* One critical component (the signer binary / daemon) is responsible for handling cryptographic operations; signing, private keys, encryption/decryption of keystore files. +* The signer binary has a well-defined 'external' API. +* The 'external' API is considered UNTRUSTED. +* The signer binary also communicates with whatever process that invoked the binary, via stdin/stdout. + * This channel is considered 'trusted'. Over this channel, approvals and passwords are communicated. + +The general flow for signing a transaction using e.g. geth is as follows: +![image](sign_flow.png) + +In this case, `geth` would be started with `--externalsigner=http://localhost:8550` and would relay requests to `eth.sendTransaction`. + ## Communication ### External API @@ -81,9 +96,9 @@ All hex encoded values must be prefixed with `0x`. ### account_new #### Create new password protected account + The signer will generate a new private key, encrypts it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and stores it in the keystore directory. -The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving -lost accounts. +The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving lost accounts. #### Arguments @@ -99,9 +114,7 @@ None "id": 0, "jsonrpc": "2.0", "method": "account_new", - "params": [ - "my password" - ] + "params": [] } { @@ -612,4 +625,9 @@ put together is a bit of a hack into the http server. This could probably be gre * There needs to be a very good structure around rules. Either a full language (lua/js) or a limited but flexible syntax based on e.g. json/yaml. Kind of like a firewall ruleset. * This implies that the signer would remember passwords, which is very problematic. However, a good UI implementation will want these things, and it would be better to implement it once in the signer, than having UI:s develop their own remember-password logic. + * See [rules.md](rules.md) for more info about this. +* Another potential thing to introduce is pairing. + * To prevent spurious requests which users just accept, implement a way to "pair" the caller with the signer (external API). + * Thus geth/mist/cpp would cryptographically handshake and afterwards the caller would be allowed to make signing requests. + * This feature would make the addition of rules less dangerous. \ No newline at end of file diff --git a/cmd/signer/main.go b/cmd/signer/main.go index d0b5c955b0..3953a5584d 100644 --- a/cmd/signer/main.go +++ b/cmd/signer/main.go @@ -217,20 +217,23 @@ func testExternalUI(api *SignerAPI) { } -// Create Account -// curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_new","params":["test"],"id":67}' localhost:8550 +/** +//Create Account + +curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_new","params":["test"],"id":67}' localhost:8550 // List accounts -// curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_list","params":[""],"id":67}' http://localhost:8550/ + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_list","params":[""],"id":67}' http://localhost:8550/ // Make Transaction // safeSend(0x12) // 4401a6e40000000000000000000000000000000000000000000000000000000000000012 -/* +// supplied abi +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":["0x82A2A876D39022B3019932D30Cd9c97ad5616813",{"gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"test"],"id":67}' http://localhost:8550/ -curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":["0x82A2A876D39022B3019932D30Cd9c97ad5616813",{"gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"}],"id":67}' http://localhost:8550/ +// Not supplied +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":["0x82A2A876D39022B3019932D30Cd9c97ad5616813",{"gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"}],"id":67}' http://localhost:8550/ - -curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":["0x82A2A876D39022B3019932D30Cd9c97ad5616813",{"gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"test"],"id":67}' http://localhost:8550/ -*/ +**/ diff --git a/cmd/signer/pythonsigner.py b/cmd/signer/pythonsigner.py index 0a216310e9..a449e84c66 100644 --- a/cmd/signer/pythonsigner.py +++ b/cmd/signer/pythonsigner.py @@ -86,8 +86,8 @@ class StdIOHandler(): return { "approved" : False, - "transaction" : transaction, - "from" : _from, + #"transaction" : transaction, + # "from" : _from, # "password" : None, } diff --git a/cmd/signer/rules.md b/cmd/signer/rules.md new file mode 100644 index 0000000000..1b761f1120 --- /dev/null +++ b/cmd/signer/rules.md @@ -0,0 +1,107 @@ +# Rules + +The `signer` binary needs to have customizeable rules. Typical scenarios: + +* I want to auto-approve transactions with contract `CasinoDapp`, with up to `0.05 ether` in value to maximum `1 ether` per 24h period +* I want to auto-approve transaction to contract `EthAlarmClock` with `data`=`0xdeadbeef`, if `value=0`, `gas < 44k` and `gasPrice < 40Gwei` + + +In order to reach this, there are two problems to solve + +1. Rule Implementation: how to create, manage and interpret rules in a flexible but secure manner +2. Credential managements and credentials; how to provide auto-unlock without exposing keys unnecessarily. + +The section below deals with both of them + +## Rule Implementation + +### Alt 1: javascript + +In this implementation, the rules would be implemented as a `js` file; which implements the same methods as the `json-rpc` methods +defined in the UI protocol. Example: + +```javascript + +// Approve transactions to a certain contract if value is below a certain limit +function ApproveTx(tx, from, call_info, metadata){ + + var limit = big.Newint("0xb1a2bc2ec50000") + + if (tx.to.String() == "0xae967917c465db8578ca9024c205720b1a3651A9" && + tx.value.Cmp(limit) < 0){ + return "Approve" + } +} + +//Approve listings if request made from IPC +function ApproveListing(accounts, metadata){ + if (metadata.scheme == "ipc"){ return "Approve"} +} + +``` + +In this case, whenever the external API was called, the `signer` would load `ruleset.js` and invoke the corresponding method. These would be +the possible cases: + +1. JS returns "Approve" -> auto-approve +2. JS returns "Reject" -> auto-reject +3. Method not implemented, or something else is returned -> pass on to regular UI channel. + +In the example above, the rule about "1 ether per 24h period" is not implemented; in order to allow for such rules, some sort of history-lookup needs to be implemented. + +#### Security considerations + +##### Security of ruleset + +Some security precautions can be made, such as: + +* Never load `ruleset.js` unless the file is `readonly` (`r-??-??-?`). If the user wishes to modify the ruleset, he must make it writeable and then set back to readonly. + * This is to prevent attacks where files are dropped on the users disk. +* Since we're going to have to have some form of secure storage (not defined in this section), we could also store the `sha3` of the `ruleset.js` file in there. + * If the user wishes to modify the ruleset, he'd then have to perform e.g. `signer --attest /path/to/ruleset --credential ` + +##### Security of implementation + +The drawbacks of this very flexible solution is that the `signer` needs to contain a javascript engine. This is pretty simple to implement, since it's already +implemented for `geth`. There are no known security vulnerabilities in, nor have we had any security-problems with it so far. + +The javascript engine would be an added attack surface; but if the validation of `rulesets` is made good (with hash-based attestation), the actual javascript cannot be considered +an attack surface -- if an attacker can control the ruleset, a much simpler attack would be to implement an "always-approve" rule instead of exploiting the js vm. The only benefit +to be gained from attacking the actual `signer` process from the `js` side would be if it could somehow extract cryptographic keys from memory. + +##### Security in usability + +Javascript is flexible, but also easy to get wrong, especially when users assume that `js` can handle large integers natively. Typical errors +include trying to multiply `gasCost` with `gas` without using `bigint`:s. + +It's unclear whether any other DSL could be more secure; since there's always the possibility of erroneously implementing a rule. + + +## Credential management + +The ability to auto-approve transaction means that the signer needs to have necessary credentials to decrypt keyfiles. These passwords are hereafter called `ksp` (keystore pass). + +### Example implementation + +Upon startup of the signer, the signer is given a switch: `--seed ` +The `seed` contains a blob of bytes, which is the master seed for the `signer`. + +The `signer` uses the `seed` to: + +* Generate the `path` where the settings are stored. + * `./settings/1df094eb-c2b1-4689-90dd-790046d38025/vault.dat` + * `./settings/1df094eb-c2b1-4689-90dd-790046d38025/rules.js` +* Generate the encryption password for `vault.dat`. + +The `vault.dat` would be an encrypted container storing the following information: + +* `ksp` entries +* `sha256` hash of `rules.js` +* Information about pair:ed callers (not yet specified) + +### Security considerations + +This would leave it up to the user to ensure that the `path/to/masterseed` is handled in a secure way. It's difficult to get around this, although one could +imagine leveraging OS-level keychains where supported. The setup is however in general similar to how ssh-keys are stored in `.ssh/`. + + diff --git a/cmd/signer/sign_flow.png b/cmd/signer/sign_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0f3cc5d58b9bd142a920525fd339e2bd0776a5 GIT binary patch literal 36397 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 Jj3cLi{67My(TV^7 literal 0 HcmV?d00001