Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Vaults RPCs #4366

Merged
merged 5 commits into from
Feb 5, 2017
Merged

Vaults RPCs #4366

merged 5 commits into from
Feb 5, 2017

Conversation

svyatonik
Copy link
Collaborator

This is second part of work on vaults (https://github.com/ethcore/parity/issues/3501).
Outline: new RPCs are introduced + meta for 'vault accounts' is populated with vault field.
I have changed some RPCs + have couple of concerns:

  1. parity_changeVaultPassword(name, new) changed to parity_changeVaultPassword(name, old, new). To me it is strange that, for example, copying account, signing message, etc. require account password && this action does not. So anyone with access to RPC could create vault && move all available accounts there, even if he had no access to these accounts => get full access to the account. Please insist, if you think that's ok - I'll change back to proposed prototype.
  2. parity_changeVault(address, newVault) changed to parity_changeVault(address, newVault, oldPassword, newPassword) because of same reasons as above. Again - this is just my proposal && it can be reverted to original prototype.
  3. the issue stated that there's some parity_getAddressMeta RPC method. I haven't found one on master - so most probably it is in development, or will be created in future. So I'm adding vault field to account' meta field at the lowest level possible (in VaultDiskDirectory)
  4. the same account can exist in two vaults. The simplest way to reproduce is to cp vault1 vault2. In parity_changeVault there's no argument, which is responsible for 'origin vault' => currently I've selected approach similar to the one, selected in EthMultiStore - choose the first matching account (matching here means that address && password are the same). Maybe there should be another way to deal with this? Another argument for parity_changeVault or move all matching accounts? Please ping me, if you think I've selected wrong way.

@svyatonik svyatonik added the A0-pleasereview 🤓 Pull request needs code review. label Jan 31, 2017
@gavofyork
Copy link
Contributor

1 & 2. so the attack case you're suggesting is Alice opens up her vault V, Bob gains access to the signer RPCs, creates a new vault W with a randomised password and moves all of Alice's keys from V into W?
this would cause Alice some annoyance as she would lose knowledge of the keys' metadata. however, her keys' secrets would still be as accessible as they were; Bob wouldn't gain "full access" to them.
furthermore, these RPCs are part of the restricted set and are known to be sensitive and able to cause grief if misused. as such they are only available to trusted components like the Signer/Parity Wallet and if Bob has access to these RPCs, he can cause substantial grief anyway.
the issue with forcing the RPC to require the vault password is that introduce a temptation for RPC clients (like authors of the UI) cache a plain-text password client-side to avoid unnecessary user interaction. plain-text caching in languages & REs not-designed for security would expose the password to a greater attack surface and could reasonably lead to an overall reduction in security.

this is a much greater argument for (2) than (1), however since (2) is ultimately reducible to multiple (1)s, it makes little sense to require the password for (2) and not (1).

  1. in fact the RPC i was thinking of was parity_getAccountsInfo, which returns the metadata. there are corresponding parity_setAccountMeta in ParityAccounts RPC.

  2. perhaps just alter any call which can change/create a new to changeVault, createAccount, ... to return an error if the name already exists. can be a separate PR though.

@gavofyork gavofyork added M4-core ⛓ Core client code / Rust. M6-rpcapi 📣 RPC API. labels Jan 31, 2017
@svyatonik
Copy link
Collaborator Author

@gavofyork
1 & 2. Yes - that's exactly scenario, that I was thinking about. But I still do not understand - why

...she would lose knowledge of the keys' metadata. however, her keys' secrets would still be as accessible as they were...

Currently both secret and meta for vault accounts are encrypted with the same password (which is also vault password && it is the same for all accounts from this vault) => if Bob will change password for Alice' vault or move accounts from Alice' vault to Bob's vault, it will get "full access" to both the secret and meta. Maybe I'm wrong && missing something? Could you please explain?
Also - at the beginning I was thinking about that every account in the root directory is actually a small vault (which contains single account). And change_password() for the single account is basically the same that change_vault_password(). But the former requires old password && the latter does not. It seems strange.
Or do you mean that vault accounts remain 'unlocked' for all the time vault is opened? I.e. when sign is called for the vault account, UI won't ask the password (because we have already opened the vault with password) && pass password = empty string && server-side will ignore passed password && will use its own cached password to sign the message? If that's true, then I get it wrong. I'll update the PR then.
3. Cool - I'll add a test for it
4. But in my scenario it is not created, it is copied. Imagine another, a little bit more adequate:

importGethKeys(); // address1 is imported
createNewVault("vault1");
moveToVault("address1", "vault1");
closeVault("vault1"); // here we forget that address1 ever exists
importGethKeys(); // address1 is imported again, as it is not yet in keys directory
createNewVault("vault2");
moveToVault("address1", "vault2");
openVault("vault1"); // we have opened 2nd vault with address1 => there are 2 opened vaults, both contain address1-account

@svyatonik
Copy link
Collaborator Author

OK - looks like I have an issue here:

Currently both secret and meta for vault accounts are encrypted with the same password (which is also vault password && it is the same for all accounts from this vault)

Meta must be encrypted with vault password && every account still will have its own password (to encrypt secret). Then everything seems logical. I'll update PR

@svyatonik svyatonik closed this Jan 31, 2017
@svyatonik
Copy link
Collaborator Author

svyatonik commented Feb 1, 2017

Changes outline:

  1. vault password is used to encrypt vault accounts' meta. Every vault account still have its own password to protect secret (most of chnages)
  2. added test for (3) above
  3. postponed solution of (4) above by adding account_ref() methof
  4. reverted RPC method prototypes to proposed in original issue

@svyatonik svyatonik reopened this Feb 1, 2017
Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Grubmles about RPC namespace.


/// Create new vault.
#[rpc(name = "parity_newVault")]
fn create_vault(&self, String, String) -> Result<bool, Error>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think those methods should be part of parity_accounts namespace (so that they are not expoed to dapps by default)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done, thanks for clarification

fn account_ref(&self, address: &Address) -> Result<StoreAccountRef, Error> {
self.reload_accounts()?;
self.cache.read().keys()
.filter(|r| &r.address == address)
Copy link
Collaborator

Choose a reason for hiding this comment

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

find() instead of filter.nth(0)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@tomusdrw tomusdrw added A5-grumble 🔥 Pull request has minor issues that must be addressed before merging. and removed A0-pleasereview 🤓 Pull request needs code review. labels Feb 1, 2017
@svyatonik svyatonik added A0-pleasereview 🤓 Pull request needs code review. and removed A5-grumble 🔥 Pull request has minor issues that must be addressed before merging. labels Feb 1, 2017
@gavofyork
Copy link
Contributor

gavofyork commented Feb 4, 2017

we probably want an rpc to list vaults; either by logging vaults or deriving from the directory structure. can be a different PR.

Copy link
Contributor

@gavofyork gavofyork left a comment

Choose a reason for hiding this comment

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

looks good in general but i'd like to see more comprehensive test coverage to ensure all operations behave correctly with respect to all others.

let request = r#"{"jsonrpc": "2.0", "method": "parity_changeVaultPassword", "params":["vault1", "password2"], "id": 1}"#;
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;

assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
Copy link
Contributor

Choose a reason for hiding this comment

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

should test that you can open with new password

let request = format!(r#"{{"jsonrpc": "2.0", "method": "parity_changeVault", "params":["0x{}", "vault1"], "id": 1}}"#, address.hex());
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;

assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned()));
Copy link
Contributor

Choose a reason for hiding this comment

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

should test that it no longer appears when old vault open and does appear when new vault open.

@gavofyork gavofyork added A5-grumble 🔥 Pull request has minor issues that must be addressed before merging. and removed A0-pleasereview 🤓 Pull request needs code review. labels Feb 4, 2017
@svyatonik
Copy link
Collaborator Author

@gavofyork

  1. OK - I'll update PR with RPC for listing vaults
  2. there are a lot of tests for vaults (and of course for changing passwords, moving accounts to/from vaults) in ethstore crate here:
    https://github.com/ethcore/parity/blob/master/ethstore/src/ethstore.rs
    https://github.com/ethcore/parity/blob/master/ethstore/src/dir/vault.rs
    I thought that RPC tests are more about correctness of parameters, serialization/deserialization, etc. In vaults case RPCs level is just about passing parameters to ethstore.
    => I don't think that duplicating same tests here same tests here will help with anything. Or maybe it worth moving tests from ethstore to here?

@svyatonik
Copy link
Collaborator Author

  1. done
  2. this is tested on lower level, but if you insist - I'll duplicate or move ethstore tests here

@svyatonik svyatonik added A0-pleasereview 🤓 Pull request needs code review. and removed A5-grumble 🔥 Pull request has minor issues that must be addressed before merging. labels Feb 5, 2017
@gavofyork
Copy link
Contributor

ok - missed those additional tests. should be good.

@gavofyork gavofyork merged commit 2f340a5 into master Feb 5, 2017
@gavofyork gavofyork deleted the vaults_rpcs branch February 5, 2017 15:17
@gavofyork gavofyork added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Feb 5, 2017
This was referenced Feb 8, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M4-core ⛓ Core client code / Rust. M6-rpcapi 📣 RPC API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants