Giter Club home page Giter Club logo

staking-deposit-cli's Introduction

staking-deposit-cli

GitPOAP Badge

Introduction

deposit-cli is a tool for creating EIP-2335 format BLS12-381 keystores and a corresponding deposit_data*.json file for Ethereum Staking Launchpad.

  • Warning: Please generate your keystores on your own safe, completely offline device.
  • Warning: Please backup your mnemonic, keystores, and password securely.

Please read Launchpad Validator FAQs before generating the keys.

You can find the audit report by Trail of Bits here.

Tutorial for users

Build requirements

For Linux or MacOS users

File Permissions

On Unix-based systems, keystores and the deposit_data*.json have 440/-r--r----- file permissions (user & group read only). This improves security by limiting which users and processes that have access to these files. If you are getting permission denied errors when handling your keystores, consider changing which user/group owns the file (with chown) or, if need be, change the file permissions with chmod.

Option 1. Download binary executable file

Step 1. Installation

See releases page to download and decompress the corresponding binary files.

Step 2. Create keys and deposit_data-*.json

Run the following command to enter the interactive CLI and generate keys from a new mnemonic:

./deposit new-mnemonic

or run the following command to enter the interactive CLI and generate keys from an existing:

./deposit existing-mnemonic
language Argument

The Launchpad offers many language/internationalization options. If you wish to select one as a CLI argument, it must be passed in before one of the commands is chosen.

Argument Type Description
--language String. Options: العربية, ελληνικά, English, Français, Bahasa melayu, Italiano, 日本語, 한국어, Português do Brasil, român, 简体中文. Default to English The language you wish to use the CLI in.
--non_interactive flag

Warning: with this flag, there will be no confirmation step(s) to verify the input value(s). Please use it carefully.

Argument Type Description
--non_interactive Flag Run CLI in non-interactive mode.
Commands

The CLI offers different commands depending on what you want to do with the tool.

Command Description
new-mnemonic (Recommended) This command is used to generate keystores with a new mnemonic.
existing-mnemonic This command is used to re-generate or derive new keys from your existing mnemonic. Use this command, if (i) you have already generated keys with this CLI before, (ii) you want to reuse your mnemonic that you know is secure that you generated elsewhere (reusing your eth1 mnemonic .etc), or (iii) you lost your keystores and need to recover your keys.
new-mnemonic Arguments

You can use new-mnemonic --help to see all arguments. Note that if there are missing arguments that the CLI needs, it will ask you for them.

Argument Type Description
--num_validators Non-negative integer The number of signing keys you want to generate. Note that the child key(s) are generated via the same master key.
--mnemonic_language String. Options: 简体中文, 繁體中文, český jazyk, English, Italiano, 한국어, Português, Español. Default to English The language of the mnemonic word list
--folder String. Pointing to ./validator_keys by default The folder path for the keystore(s) and deposit(s)
--chain String. mainnet by default The chain setting for the signing domain.
--execution_address (or --eth1_withdrawal_address) String. Eth1 address in hexadecimal encoded form If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in ERC-2334 format.
existing-mnemonic Arguments

You can use existing-mnemonic --help to see all arguments. Note that if there are missing arguments that the CLI needs, it will ask you for them.

Argument Type Description
--validator_start_index Non-negative integer The index of the first validator's keys you wish to generate. If this is your first time generating keys with this mnemonic, use 0. If you have generated keys using this mnemonic before, use the next index from which you want to start generating keys from (eg, if you've generated 4 keys before (keys #0, #1, #2, #3), then enter 4 here.
--num_validators Non-negative integer The number of new signing keys you want to generate. Note that the child key(s) are generated via the same master key.
--folder String. Pointing to ./validator_keys by default The folder path for the keystore(s) and deposit(s)
--chain String. mainnet by default The chain setting for the signing domain.
--execution_address (or --eth1_withdrawal_address) String. Eth1 address in hexadecimal encoded form If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in ERC-2334 format.
Successful message

You will see the following messages after successfully generated the keystore(s) and the deposit(s):

Creating your keys:               [####################################]  <N>/<N>
Creating your keystores:          [####################################]  <N>/<N>
Creating your depositdata:        [####################################]  <N>/<N>
Verifying your keystores:         [####################################]  <N>/<N>
Verifying your deposits:          [####################################]  <N>/<N>

Success!
Your keys can be found at: <YOUR_FOLDER_PATH>
generate-bls-to-execution-change Arguments

You can use bls-to-execution-change --help to see all arguments. Note that if there are missing arguments that the CLI needs, it will ask you for them.

Argument Type Description
--bls_to_execution_changes_folder String. Pointing to ./bls_to_execution_changes by default The folder path for the bls_to_execution_change-* JSON file(s)
--chain String. mainnet by default The chain setting for the signing domain.
--mnemonic String. mnemonic split by space. The mnemonic you used to create withdrawal credentials.
--mnemonic_password Optional string. Empty by default. The mnemonic password you used in your key generation. Note: It's not the keystore password.
--validator_start_index Non-negative integer The index position for the keys to start generating withdrawal credentials in ERC-2334 format.
--validator_indices String of integer(s) A list of the chosen validator index number(s) as identified on the beacon chain. Split multiple items with whitespaces or commas.
--bls_withdrawal_credentials_list String of hexstring(s). A list of the old BLS withdrawal credentials of the given validator(s). It is for confirming you are using the correct keys. Split multiple items with whitespaces or commas.
--execution_address (or --eth1_withdrawal_address) String. Eth1 address in hexadecimal encoded form If this field is set and valid, the given Eth1 address will be used to create the withdrawal credentials. Otherwise, it will generate withdrawal credentials with the mnemonic-derived withdrawal public key in ERC-2334 format.
--devnet_chain_setting String. JSON string '{"network_name": "<NETWORK_NAME>", "genesis_fork_version": "<GENESIS_FORK_VERSION>", "genesis_validator_root": "<GENESIS_VALIDATOR_ROOT>"}' The custom chain setting of a devnet or testnet. Note that it will override your --chain choice.

Option 2. Build deposit-cli with native Python

Step 0. Python version checking

Ensure you are using Python version >= Python3.8:

python3 -V
Step 1. Installation

Install the dependencies:

pip3 install -r requirements.txt
python3 setup.py install

Or use the helper script:

./deposit.sh install
Step 2. Create keys and deposit_data-*.json

Run one of the following command to enter the interactive CLI:

./deposit.sh new-mnemonic

or

./deposit.sh existing-mnemonic

You can also run the tool with optional arguments:

./deposit.sh new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
./deposit.sh existing-mnemonic --num_validators=<NUM_VALIDATORS> --validator_start_index=<START_INDEX> --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
Language Argument

See here for --language arguments.

Commands

See here

Arguments

See here for new-mnemonic arguments See here for existing-mnemonic arguments See here for generate-bls-to-execution-change arguments

Successful message

See here

Option 3. Build deposit-cli with virtualenv

Step 0. Python version checking

Ensure you are using Python version >= Python3.8:

python3 -V
Step 1. Installation

For the virtualenv users, you can create a new venv:

pip3 install virtualenv
virtualenv venv
source venv/bin/activate

and install the dependencies:

python3 setup.py install
pip3 install -r requirements.txt
Step 2. Create keys and deposit_data-*.json

Run one of the following command to enter the interactive CLI:

python3 ./staking_deposit/deposit.py new-mnemonic

or

python3 ./staking_deposit/deposit.py existing-mnemonic

You can also run the tool with optional arguments:

python3 ./staking_deposit/deposit.py new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
python3 ./staking_deposit/deposit.py existing-mnemonic --num_validators=<NUM_VALIDATORS> --validator_start_index=<START_INDEX> --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
Language Argument

See here for --language arguments.

Commands

See here

Arguments

See here for new-mnemonic arguments See here for existing-mnemonic arguments See here for generate-bls-to-execution-change arguments

Option 4. Use Docker image

Step 1. Build the docker image

Run the following command to locally build the docker image:

make build_docker
Step 2. Create keys and deposit_data-*.json

Run the following command to enter the interactive CLI:

docker run -it --rm -v $(pwd)/validator_keys:/app/validator_keys ethereum/staking-deposit-cli

You can also run the tool with optional arguments:

docker run -it --rm -v $(pwd)/validator_keys:/app/validator_keys ethereum/staking-deposit-cli new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --folder=<YOUR_FOLDER_PATH>

Example for 1 validator on the Prater testnet using english:

docker run -it --rm -v $(pwd)/validator_keys:/app/validator_keys ethereum/staking-deposit-cli new-mnemonic --num_validators=1 --mnemonic_language=english --chain=prater
Arguments

See here

Successful message

See here


For Windows users

Option 1. Download binary executable file

Step 1. Installation

See releases page to download and decompress the corresponding binary files.

Step 2. Create keys and deposit_data-*.json

Run one of the following command to enter the interactive CLI:

deposit.exe new-mnemonic

or

deposit.exe existing-mnemonic

You can also run the tool with optional arguments:

deposit.exe new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
deposit.exe existing-mnemonic --num_validators=<NUM_VALIDATORS> --validator_start_index=<START_INDEX> --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
Language Argument

See here for --language arguments.

Commands

See here

Arguments

See here for new-mnemonic arguments See here for existing-mnemonic arguments See here for generate-bls-to-execution-change arguments

Option 2. Build deposit-cli with native Python

Step 0. Python version checking

Ensure you are using Python version >= Python3.8 (Assume that you've installed Python 3 as the main Python):

python -V
Step 1. Installation

Install the dependencies:

pip3 install -r requirements.txt
python setup.py install

Or use the helper script:

sh deposit.sh install
Step 2. Create keys and deposit_data-*.json

Run one of the following command to enter the interactive CLI:

./deposit.sh new-mnemonic

or

./deposit.sh existing-mnemonic

You can also run the tool with optional arguments:

./deposit.sh new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
./deposit.sh existing-mnemonic --num_validators=<NUM_VALIDATORS> --validator_start_index=<START_INDEX> --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
Language Argument

See here for --language arguments.

Commands

See here

Arguments

See here for new-mnemonic arguments See here for existing-mnemonic arguments See here for generate-bls-to-execution-change arguments

Option 3. Build deposit-cli with virtualenv

Step 0. Python version checking

Ensure you are using Python version >= Python3.8 (Assume that you've installed Python 3 as the main Python):

python -V
Step 1. Installation

For the virtualenv users, you can create a new venv:

pip3 install virtualenv
virtualenv venv
.\venv\Scripts\activate

and install the dependencies:

python setup.py install
pip3 install -r requirements.txt
Step 2. Create keys and deposit_data-*.json

Run one of the following command to enter the interactive CLI:

python .\staking_deposit\deposit.py new-mnemonic

or

python .\staking_deposit\deposit.py existing-mnemonic

You can also run the tool with optional arguments:

python .\staking_deposit\deposit.py new-mnemonic --num_validators=<NUM_VALIDATORS> --mnemonic_language=english --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
python .\staking_deposit\deposit.pyexisting-mnemonic --num_validators=<NUM_VALIDATORS> --validator_start_index=<START_INDEX> --chain=<CHAIN_NAME> --folder=<YOUR_FOLDER_PATH>
Language Argument

See here for --language arguments.

Commands

See here

Arguments

See here for new-mnemonic arguments See here for existing-mnemonic arguments See here for generate-bls-to-execution-change arguments

Development

Install basic requirements

python3 -m pip install -r requirements.txt
python3 setup.py install

Install testing requirements

python3 -m pip install -r requirements_test.txt

Run tests

python3 -m pytest .

Building Binaries

Developers Only

Mac M1 Binaries

👋This is not the section you are looking for.👋 If you are trying to build the binary on macos with an M1 Mac and you are using pyenv to manage your python version. You'll probably need to reinstall a given python version using:

env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.10.3

staking-deposit-cli's People

Contributors

burz avatar carlbeek avatar ceroma avatar colfax23 avatar dependabot[bot] avatar djrtwo avatar hwwhww avatar jeremie-h avatar johnwestlund avatar lightclient avatar marioevz avatar maxwellt avatar mgcrea avatar miguelmota avatar protortyp avatar raekye avatar shicks avatar vadorovsky avatar vbuterin avatar wackerow avatar yorickdowne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

staking-deposit-cli's Issues

Missing module `pip3`

Running @ 4ff0754.

On macOS, get an error during installation with ./deposit.sh install that I'm missing pip3.

In my case I think I already had pip3 installed before I installed the version of python3 currently on top of my PATH so they aren't aware of each other.

Can we change that line in the install script to just use pip?

https://github.com/ethereum/eth2.0-deposit-cli/blob/master/deposit.sh#L7

Otherwise we should detect if the user has pip3 and install if it is missing.

asks for password before keys are generated

I run the deposit.exe
Asks how many validators
Asks for language
Asks which testnet
Immediately asks for "password that secures your validator keystore(s)"
A) I haven't generated anything yet
B) I'm unable to type anything in this space

Help/Thoughts?

[ToB Audit] #7: PyInstaller binaries should be distributed with signatures

Description

The deposit tool is distributed as binary files compiled using PyInstaller, but without any way for users to verify their authenticity.

The deposit tool is compiled to a single binary using PyInstaller to be released on GitHub.

However, there is no way for users to check that these binaries are compiled by someone
from the Ethereum 2.0 development team.

Exploit Scenario

Eve compromises the security of the GitHub account used to upload the deposit binaries and replaces the binaries with backdoored versions. Alice downloads the released binaries and her keys are compromised.

Recommendation

Short term, include signatures to allow users to verify the released binaries. We recommend using gpg with public keys uploaded to public servers.
Long term, review the chain of trust of the precompiled releases used to generate private keys.

Minor UX improvements

  • Clear screen in-between build and key generation
  • Progress bars during key generation, validation, etc (process can be slow due to scrypt in keystores)
  • Password minimum length requirement?

[ToB Audit] #1: Generated mnemonic could be leaked (via clipboard or terminal scrollback)

Description

The Deposit CLI tool is responsible for generating BLS key pairs. This tool implements a series of EIP standards that specify how to derive these key pairs from a mnemonic phrase. Specifically, a random mnemonic phrase is generated by the tool and then it is used to derive the BLS key pairs. This phrase is given to the user so that their keys can be regenerated in the future.
Since knowledge of the mnemonic phrase allows you to immediately recover the BLS private keys, this phrase is kept secret. Therefore, it is imperative that the generated phrase is delivered to the user as securely as possible.
Currently, when the phrase is generated, it is output into the terminal so that the user can copy down this phrase to potentially use at a later time. However, the terminal buffer is not properly cleared. So, for example, if a Linux user is using gnome-terminal, the mnemonic phrase is never cleared, and the phrase can be recovered at a later time by simply scrolling up. This also applies to the macOS terminal and iTerm2.
In addition to this, the clipboard is not blocked and is never cleared. Therefore, if a user copies this phrase from the terminal, it could remain in the clipboard for an indefinite period of time.

Exploit Scenario

Alice uses the Deposit CLI tool to generate her secret keys. An attacker, Eve, gains access to her device and is able to steal her secret mnemonic phrase by extracting it from her terminal or clipboard. Alternatively, Alice visits a malicious website hosted by Eve that accesses Alice’s clipboard and recovers the secret phrase.

Recommendation

Short term, properly clear the terminal buffer after the tool is no longer being used. This is dependent on the operation system and should be implemented carefully. In addition, clear either the clipboard after the tool has finished or block the user from copying the data altogether.
Long term, consider only presenting the user with the secret mnemonic phrase for a short period of time (e.g., a few minutes), and then clearing this information upon timing out.

Add command to create top-up deposit data

Issue

By default, deposit-cli creates keys and deposit_data all in one workflow.
Users may want to create deposit_data more flexibly.

How to solve it

The top-up command needs the following arguments to create and sign a new DepositData object:

  • pubkey
  • withdrawal_credentials
  • amount
  • signature
  • keystore
  • password

Explain what is the privacy level of the generated files.

Since this cli is going to be used by people that might not be intimate with crypto technicalities, I think it would be great to add some explanation at the end once the files are generated.

For instance (not sure if those statement are even valid!):

  • Even is your keystore is encrypted with the passphrase you provided it must be kept private as someone could brute-force your passphrase and steal your staked funds (not sure if possible before phase 1).

  • Your deposit_data should be kept private as it does contain some identifying information, but sharing it won't risk your staked funds.

I really like the very detailed, "proceed with caution" approach of the medella launchpad and I think the CLI could replicate this.

Could even be worth to add a confirmation text (with the privacy implications) before the generation (like a [y/n] confirm), optionally bypassed by a flag (eg. --yes or --skip-disclaimer, etc.)

Could work on a PR if you like the idea & once the wording is settled.

./deposit.sh install command fails with permission issue on Linux Ubuntu

System : Linux Ubuntu
Command -
./deposit.sh install
Error -

    cytoolz/dicttoolz.c:17:10: fatal error: Python.h: No such file or directory
     #include "Python.h"
              ^~~~~~~~~~
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-phtudhwx/cytoolz/setup.py'"'"'; __file__='"'"'/tmp/pip-install-phtudhwx/cytoolz/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-6w7rqm5q/install-record.txt --single-version-externally-managed --compile --user --prefix= Check the logs for full command output. ```

[ToB Audit] #5: Use of assert will be removed when the bytecode is optimized

Description

The deposit tool uses assert to make sure the input for the tool is correct, however, such code is going to be removed when the bytecode is compiled with optimizations enabled.
The deposit tool contains several places where important verifications are performed using the assert statement:

@click.password_option(prompt='Type the password that secures your validator keystore(s)')
def main(num_validators: int, mnemonic_language: str, folder: str, chain: str, password: str) -> None:
...
click.echo('Saving your keystore(s).')
keystore_filefolders = credentials.export_keystores(password=password, folder=folder) click.echo('Creating your deposit(s).')
deposits_file = credentials.export_deposit_data_json(folder=folder) click.echo('Verifying your keystore(s).')
assert credentials.verify_keystores(keystore_filefolders=keystore_filefolders,
password=password)
click.echo('Verifying your deposit(s).')
assert verify_deposit_data_json(deposits_file) click.echo('\nSuccess!\nYour keys can be found at: %s' % folder) click.pause('\n\nPress any key.')

However, these checks are going to be removed, if the bytecode is optimized using the -O
flag, as indicated with the Python documentation:

-O Remove assert statements and any code conditional on the value of __debug__; augment the filename for compiled (bytecode) files by adding .opt-1 before
the .pyc extension.

It is also worth mentioning that the tool will fail to run in the optimized mode, because the
asserts removed in path_to_nodes function contain a side effect.

Exploit Scenario

Alice compiles the deposit tool with optimizations enabled. Later, she uses the tool, but the lack of validation produces invalid results without any visible fail.

Recommendation

Short term, replace the use of assertion for proper input validation and do not include assertions with side effects.
Long term, review every feature of the Python language you use, in case it has a different behavior when the bytecode is optimized.

Add tools to verify the outputs

It would be great if users can verify the outputs after they created the keys and deposit data.

  • mnemonic
  • withdrawal
  • deposit_data.json

[ToB Audit] #4: Saving large JSON integers could result in interoperability issues

Description

The parsing of JSON integers generated by the deposit tool differs from mainstream implementations such as NodeJS and jq.
The JSON standard warns about certain "interoperability problems" in numeric types outside the range [-(253)+1, (253)-1]. This issue is caused by some widely used JSON implementations employing IEEE 754 (double precision) numbers to implement integer numbers. For instance, if the deposit tool saves the following amount value "1152921504606846976" (2**60), it is serialized as the expected value 1152921504606846976.
Figure 4.1 Part of a JSON file produced by the deposit tool. However, NodeJS 10 and jq 1.5 parse it as 1152921504606847000.

Exploit Scenario

Alice uses the deposit tool to generate some JSON files. Later, a third-party software reads Alice's JSON but interprets this number differently than the deposit tool interpretation, causing unexpected behavior for Alice.

Recommendation

Short term, use strings instead of JSON numeric values to implement the amount field.
Long term, provide a recommended JSON implementation to use when interacting with the JSON files generated by the deposit tool.

References

Production checklist

TODOs

  • Test eth2deposit.deposit (#14)
  • Test eth2deposit.credentials
  • Windows user instruction
  • Better docs
  • important Go through it aganist the final production version spec again.

@CarlBeek
I add some backlogs here, feel free to update this issue.

ModuleNotFoundError: No module named 'py_ecc'

Followed all steps and have ubuntu 18.04 with
python3.7 --version
Python 3.7.8
pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.7)

git clone https://github.com/ethereum/eth2.0-deposit-cli.git
cd eth2.0-deposit-cli
pip3 install -r requirements.txt
python3.7 setup.py install
#all above worked without issues

python3.7 ./eth2deposit/deposit.py --num_validators 1 --chain medalla

Traceback (most recent call last):
File "./eth2deposit/deposit.py", line 5, in
from eth2deposit.credentials import (
File "/usr/local/lib/python3.7/dist-packages/eth2deposit-0.2.1-py3.7.egg/eth2deposit/credentials.py", line 5, in
from py_ecc.bls import G2ProofOfPossession as bls
ModuleNotFoundError: No module named 'py_ecc'

Add Medalla as a chain option

We need to add in the Medalla eth2 testnet as a chain option to generate the keys.

An example command that should work: ./deposit.sh --num_validators 1 --chain medalla

We should also add it to the helpful error here shown here:
Screen Shot 2020-07-22 at 8 48 34 PM

Docker install

A docker file is a good backup mechanism for running these scripts for users. In particular, it provides an environment that is guaranteed to work irrespective of one's local setup.

404 when reloading pages

I'd gotten through the acknowledgements before realising I'd need to switch browsers so I had Metamask available. When I copied the current URL (https://serene-carson-3331d5.netlify.app/generate-keys) to the other browser I got a 404 page.

Similarly reloading any page (e.g https://serene-carson-3331d5.netlify.app/congratulations) seems to give a 404.

This may just be related to how the current version is deployed but it would be nice if the URLs in the browser bar actually worked, even if they needed to use fragment identifiers instead of "real" paths.

[ToB Audit] #8: Certain encodings can make passwords impossible to input

Description

The use of certain characters (e.g., ñ) in the password will produce different results according to the terminal encoding and how the password is provided.
The deposit tool was implemented to accept UTF-8 input, forcing the conversion to that encoding at each point of the input handling:

@staticmethod
def _process_password(password: str) -> bytes:
"""
Encode password as NFKD UTF-8 as per: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2335.md#password-requirements
"""
password = normalize('NFKD', password)
password = ''.join(c for c in password if ord(c) not in UNICODE_CONTROL_CHARS) return password.encode('UTF-8')

However, it seems that the tool can still fail with the following list of errors when it is run using by forcing LANG="en_US-iso8859-1", iso8859-1 as the terminal input encoding or the password specified in the command line:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcf1' in position 0: surrogates not allowed

Additionally, users in Windows could have issues since the use of UTF-8 in that operating
system is not enabled by default.

Exploit Scenario

Alice generates a password with certain characters in one operating system. Later, she moves to another platform with an unsupported encoding. As a result of that, she is unable to re-enter her password.

Recommendation

Short term, validate the configuration of terminal encoding and system encoding. Properly document the recommended configuration for users.

Long term, review the use of text encoding in each step of the key generation and storage. Properly document each corner case, in particular, for non-Latin languages.

Verification of withdrawal credentials

It is very scary to me that withdrawal credentials are not verified at any point after generation. Adding a withdrawal signature & and the full withdrawal public key would allow verification of the key and it's encoding which would be a comforting sanity check.

[ToB Audit] #9: Naming of the resulting JSON files can be misleading

Trail of Bits audit report

Description

The naming convention of the output files depends on the current time and can confuse users in case of generating several keys in the same directory.

The ETH2 deposit tool will ask the user some information to generate an encrypted private key and deposit information. After the key and the deposit information is computed, the tool will save two JSON files in an output folder, using the filenames to match when they where generated:

def save_signing_keystore(self, password: str, folder: str) -> str:
    keystore = self.signing_keystore(password)
    filefolder = os.path.join(folder, 'keystore-%s-%i.json' % (keystore.path.replace('/', '_'), time.time()))
    keystore.save(filefolder)
    return filefolder
def export_deposit_data_json(self, folder: str) -> str:
    deposit_data = [cred.deposit_datum_dict for cred in self.credentials]
    filefolder = os.path.join(folder, 'deposit_data-%i.json' % time.time())
    with open(filefolder, 'w') as f:
        json.dump(deposit_data, f, default=lambda x: x.hex())
    return filefolder

However, since the time.time() function is called two times, the names of the JSON files are not guaranteed to match. This could confuse users if they generate several keys in the same folder, which is the default option.

Exploit Scenario

Alice generates several validator keys with their corresponding deposit files. When uploading the deposit file to the Eth2 Launch Pad, she confuses the one she wants and uploads the incorrect one.

Recommendation

Short term, make sure the keystore and deposit file always have matching filenames.
Long term, make sure users have enough information to know exactly which deposit file they want to upload.

./deposit.sh install failure on Mac OS

Running ./deposit.sh install on Mac OS failed to install because of lack of write permissions in /Library/Python/3.7:

Installing collected packages: eth-hash, eth-typing, toolz, cytoolz, eth-utils, mypy-extensions, cached-property, py-ecc, pycryptodome, click, six, pyrsistent, lru-dict, ssz
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/Library/Python/3.7'
Consider using the `--user` option or check the permissions.

That output was hidden in the middle of the install output though so I missed it initially.

Creating a venv and then rerunning ./deposit.sh install worked correctly. ie:

python3 -m venv env
source env/bin/activate
./deposit.sh install

after i input the keystore password ,it's always staying at that moment

Administrator@BlockStar-Desk MINGW64 ~/eth2.0-deposit-cli (master) $ sh deposit.sh --num_validators=1 --mnemonic_language=english msys Running deposit-cli... Type the password that secures your validator keystore(s): 1qaZsdfg4398?
when i have input password , it stay there forever,

Allow for creating a `deposit_data.json` within a given range for a pre-existing seed phrase

At the beginning of Medalla, I activated 20 validators, and 19 of them have since exited. I wanted to activate another 20 using the ETH2 Medalla Launchpad, but reuse the same/existing seed phrase used in the original 20.

Since this tool is so closely tied to the Launchpad, I would like to be able to generate additional keys within a given index range (e.g., 20–39) for a pre-existing seed phrase.

As a bonus, this feature may also alleviate the bottlenecks experienced in MetaMask when users attempt to make deposits for a large number of validators (100+), by allowing "batches" of deposit-data.json be created.

error installing Install deposit-cli dependencies windows 10

msc82@DESKTOP-N12G70C MINGW64 /e/eth2.0-deposit-cli (master)
$ sh deposit.sh install
msys
Installing dependencies...
Collecting py-ecc==4.0.0
Using cached py_ecc-4.0.0-py3-none-any.whl (41 kB)
Collecting pycryptodome==3.9.7
Using cached pycryptodome-3.9.7-cp38-cp38-win32.whl (14.1 MB)
Collecting click==7.0
Using cached Click-7.0-py2.py3-none-any.whl (81 kB)
Collecting ssz==0.2.3
Using cached ssz-0.2.3-py3-none-any.whl (43 kB)
Requirement already satisfied: eth-typing==2.2.1 in c:\users\msc82\appdata\roaming\python\python38\site-packages (from -r requirements.txt (line 41)) (2.2.1)
Collecting eth-utils==1.8.4
Using cached eth_utils-1.8.4-py3-none-any.whl (23 kB)
Requirement already satisfied: mypy-extensions==0.4.3 in c:\users\msc82\appdata\roaming\python\python38\site-packages (from -r requirements.txt (line 49)) (0.4.3)
Collecting lru-dict==1.1.6
Using cached lru-dict-1.1.6.tar.gz (9.4 kB)
Collecting pyrsistent==0.15.7
Using cached pyrsistent-0.15.7.tar.gz (107 kB)
Requirement already satisfied: eth-hash==0.2.0 in c:\program files (x86)\python38-32\lib\site-packages (from -r requirements.txt (line 56)) (0.2.0)
Collecting cytoolz==0.10.1
Using cached cytoolz-0.10.1.tar.gz (475 kB)
Requirement already satisfied: toolz==0.10.0 in c:\users\msc82\appdata\roaming\python\python38\site-packages (from -r requirements.txt (line 61)) (0.10.0)
Collecting six==1.14.0
Using cached six-1.14.0-py2.py3-none-any.whl (10 kB)
Requirement already satisfied: cached-property==1.5.1 in c:\users\msc82\appdata\roaming\python\python38\site-packages (from -r requirements.txt (line 66)) (1.5.1)
Building wheels for collected packages: lru-dict, pyrsistent, cytoolz
Building wheel for lru-dict (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\lru-dict\setup.py'"'"'; file='"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\lru-dict\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\msc82\AppData\Local\Temp\pip-wheel-dh_o5iwn'
cwd: C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\lru-dict
Complete output (11 lines):
running bdist_wheel
running build
running build_ext
building 'lru' extension
creating build
creating build\temp.win32-3.8
creating build\temp.win32-3.8\Release
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD "-Ic:\program files (x86)\python38-32\include" "-Ic:\program files (x86)\python38-32\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\include" /Tclru.c /Fobuild\temp.win32-3.8\Release\lru.obj
lru.c
c:\program files (x86)\python38-32\include\pyconfig.h(59): fatal error C1083: Cannot open include file: 'io.h': No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe' failed with exit status 2

ERROR: Failed building wheel for lru-dict
Running setup.py clean for lru-dict
Building wheel for pyrsistent (setup.py) ... done
Created wheel for pyrsistent: filename=pyrsistent-0.15.7-cp38-cp38-win32.whl size=56526 sha256=3810c0d753020914362ebc3a388a7fc75848381e86b04889d8990aeca4bedd74
Stored in directory: c:\users\msc82\appdata\local\pip\cache\wheels\be\48\69\322d0d62b8a2eb62b4b497b10c30902d0d2cb4599ca0d4e1ba
Building wheel for cytoolz (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"'; file='"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\msc82\AppData\Local\Temp\pip-wheel-pwl4ox2k'
cwd: C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz
Complete output (60 lines):
[1/5] Cythonizing cytoolz/utils.pyx
[2/5] Cythonizing cytoolz/dicttoolz.pyx
[3/5] Cythonizing cytoolz/functoolz.pyx
[4/5] Cythonizing cytoolz/itertoolz.pyx
[5/5] Cythonizing cytoolz/recipes.pyx
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win32-3.8
creating build\lib.win32-3.8\cytoolz
copying cytoolz\compatibility.py -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils_test.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_signatures.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_version.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_init_.py -> build\lib.win32-3.8\cytoolz
creating build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried\exceptions.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried\operator.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried_init_.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\dicttoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\functoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\itertoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\recipes.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\cpython.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\dicttoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\functoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\itertoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\recipes.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz_init_.pxd -> build\lib.win32-3.8\cytoolz
creating build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\dev_skip_test.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_compatibility.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_curried.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_curried_toolzlike.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_dev_skip_test.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_dicttoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_docstrings.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_doctests.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_embedded_sigs.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_functoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_inspect_args.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_itertoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_none_safe.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_recipes.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_serialization.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_signatures.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_tlz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_utils.py -> build\lib.win32-3.8\cytoolz\tests
running build_ext
building 'cytoolz.dicttoolz' extension
creating build\temp.win32-3.8
creating build\temp.win32-3.8\Release
creating build\temp.win32-3.8\Release\cytoolz
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD "-Ic:\program files (x86)\python38-32\include" "-Ic:\program files (x86)\python38-32\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\include" /Tccytoolz/dicttoolz.c /Fobuild\temp.win32-3.8\Release\cytoolz/dicttoolz.obj
dicttoolz.c
c:\program files (x86)\python38-32\include\pyconfig.h(59): fatal error C1083: Cannot open include file: 'io.h': No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe' failed with exit status 2

ERROR: Failed building wheel for cytoolz
Running setup.py clean for cytoolz
Successfully built pyrsistent
Failed to build lru-dict cytoolz
Installing collected packages: cytoolz, eth-utils, py-ecc, pycryptodome, click, six, pyrsistent, lru-dict, ssz
Running setup.py install for cytoolz ... error
ERROR: Command errored out with exit status 1:
command: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"'; file='"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\msc82\AppData\Local\Temp\pip-record-zw5qp_n6\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files (x86)\python38-32\Include\cytoolz'
cwd: C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz
Complete output (60 lines):
[1/5] Cythonizing cytoolz/utils.pyx
[2/5] Cythonizing cytoolz/dicttoolz.pyx
[3/5] Cythonizing cytoolz/functoolz.pyx
[4/5] Cythonizing cytoolz/itertoolz.pyx
[5/5] Cythonizing cytoolz/recipes.pyx
running install
running build
running build_py
creating build
creating build\lib.win32-3.8
creating build\lib.win32-3.8\cytoolz
copying cytoolz\compatibility.py -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils_test.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_signatures.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_version.py -> build\lib.win32-3.8\cytoolz
copying cytoolz_init_.py -> build\lib.win32-3.8\cytoolz
creating build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried\exceptions.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried\operator.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\curried_init_.py -> build\lib.win32-3.8\cytoolz\curried
copying cytoolz\dicttoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\functoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\itertoolz.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\recipes.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils.pyx -> build\lib.win32-3.8\cytoolz
copying cytoolz\cpython.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\dicttoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\functoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\itertoolz.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\recipes.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz\utils.pxd -> build\lib.win32-3.8\cytoolz
copying cytoolz_init_.pxd -> build\lib.win32-3.8\cytoolz
creating build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\dev_skip_test.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_compatibility.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_curried.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_curried_toolzlike.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_dev_skip_test.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_dicttoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_docstrings.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_doctests.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_embedded_sigs.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_functoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_inspect_args.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_itertoolz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_none_safe.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_recipes.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_serialization.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_signatures.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_tlz.py -> build\lib.win32-3.8\cytoolz\tests
copying cytoolz\tests\test_utils.py -> build\lib.win32-3.8\cytoolz\tests
running build_ext
building 'cytoolz.dicttoolz' extension
creating build\temp.win32-3.8
creating build\temp.win32-3.8\Release
creating build\temp.win32-3.8\Release\cytoolz
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD "-Ic:\program files (x86)\python38-32\include" "-Ic:\program files (x86)\python38-32\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\include" /Tccytoolz/dicttoolz.c /Fobuild\temp.win32-3.8\Release\cytoolz/dicttoolz.obj
dicttoolz.c
c:\program files (x86)\python38-32\include\pyconfig.h(59): fatal error C1083: Cannot open include file: 'io.h': No such file or directory
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\cl.exe' failed with exit status 2
----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\program files (x86)\python38-32\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"'; file='"'"'C:\Users\msc82\AppData\Local\Temp\pip-install-1hbut51e\cytoolz\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\msc82\AppData\Local\Temp\pip-record-zw5qp_n6\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files (x86)\python38-32\Include\cytoolz' Check the logs for full command output.
running install
running bdist_egg
running egg_info
writing eth2deposit.egg-info\PKG-INFO
writing dependency_links to eth2deposit.egg-info\dependency_links.txt
writing top-level names to eth2deposit.egg-info\top_level.txt
file eth2deposit.py (for module eth2deposit) not found
reading manifest file 'eth2deposit.egg-info\SOURCES.txt'
writing manifest file 'eth2deposit.egg-info\SOURCES.txt'
installing library code to build\bdist.win32\egg
running install_lib
running build_py
file eth2deposit.py (for module eth2deposit) not found
copying eth2deposit\deposit.py -> build\lib\eth2deposit
file eth2deposit.py (for module eth2deposit) not found
creating build\bdist.win32\egg
creating build\bdist.win32\egg\eth2deposit
copying build\lib\eth2deposit\credentials.py -> build\bdist.win32\egg\eth2deposit
copying build\lib\eth2deposit\deposit.py -> build\bdist.win32\egg\eth2deposit
creating build\bdist.win32\egg\eth2deposit\key_handling
copying build\lib\eth2deposit\key_handling\keystore.py -> build\bdist.win32\egg\eth2deposit\key_handling
creating build\bdist.win32\egg\eth2deposit\key_handling\key_derivation
copying build\lib\eth2deposit\key_handling\key_derivation\mnemonic.py -> build\bdist.win32\egg\eth2deposit\key_handling\key_derivation
copying build\lib\eth2deposit\key_handling\key_derivation\path.py -> build\bdist.win32\egg\eth2deposit\key_handling\key_derivation
copying build\lib\eth2deposit\key_handling\key_derivation\tree.py -> build\bdist.win32\egg\eth2deposit\key_handling\key_derivation
copying build\lib\eth2deposit\key_handling\key_derivation_init_.py -> build\bdist.win32\egg\eth2deposit\key_handling\key_derivation
copying build\lib\eth2deposit\key_handling_init_.py -> build\bdist.win32\egg\eth2deposit\key_handling
copying build\lib\eth2deposit\settings.py -> build\bdist.win32\egg\eth2deposit
creating build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils\ascii_art.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils\constants.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils\crypto.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils\ssz.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils\validation.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit\utils_init_.py -> build\bdist.win32\egg\eth2deposit\utils
copying build\lib\eth2deposit_init_.py -> build\bdist.win32\egg\eth2deposit
creating build\bdist.win32\egg\tests
creating build\bdist.win32\egg\tests\test_key_handling
copying build\lib\tests\test_key_handling\test_keystore.py -> build\bdist.win32\egg\tests\test_key_handling
creating build\bdist.win32\egg\tests\test_key_handling\test_key_derivation
copying build\lib\tests\test_key_handling\test_key_derivation\test_mnemonic.py -> build\bdist.win32\egg\tests\test_key_handling\test_key_derivation
copying build\lib\tests\test_key_handling\test_key_derivation\test_path.py -> build\bdist.win32\egg\tests\test_key_handling\test_key_derivation
copying build\lib\tests\test_key_handling\test_key_derivation\test_tree.py -> build\bdist.win32\egg\tests\test_key_handling\test_key_derivation
copying build\lib\tests\test_key_handling\test_key_derivation_init_.py -> build\bdist.win32\egg\tests\test_key_handling\test_key_derivation
copying build\lib\tests\test_key_handling_init_.py -> build\bdist.win32\egg\tests\test_key_handling
byte-compiling build\bdist.win32\egg\eth2deposit\credentials.py to credentials.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\deposit.py to deposit.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling\keystore.py to keystore.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling\key_derivation\mnemonic.py to mnemonic.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling\key_derivation\path.py to path.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling\key_derivation\tree.py to tree.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling\key_derivation_init_.py to init.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\key_handling_init_.py to init.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\settings.py to settings.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils\ascii_art.py to ascii_art.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils\constants.py to constants.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils\crypto.py to crypto.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils\ssz.py to ssz.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils\validation.py to validation.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit\utils_init_.py to init.cpython-38.pyc
byte-compiling build\bdist.win32\egg\eth2deposit_init_.py to init.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling\test_keystore.py to test_keystore.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling\test_key_derivation\test_mnemonic.py to test_mnemonic.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling\test_key_derivation\test_path.py to test_path.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling\test_key_derivation\test_tree.py to test_tree.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling\test_key_derivation_init_.py to init.cpython-38.pyc
byte-compiling build\bdist.win32\egg\tests\test_key_handling_init_.py to init.cpython-38.pyc
creating build\bdist.win32\egg\EGG-INFO
copying eth2deposit.egg-info\PKG-INFO -> build\bdist.win32\egg\EGG-INFO
copying eth2deposit.egg-info\SOURCES.txt -> build\bdist.win32\egg\EGG-INFO
copying eth2deposit.egg-info\dependency_links.txt -> build\bdist.win32\egg\EGG-INFO
copying eth2deposit.egg-info\top_level.txt -> build\bdist.win32\egg\EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist\eth2deposit-0.2.0-py3.8.egg' and adding 'build\bdist.win32\egg' to it
removing 'build\bdist.win32\egg' (and everything under it)
Processing eth2deposit-0.2.0-py3.8.egg
Removing c:\program files (x86)\python38-32\lib\site-packages\eth2deposit-0.2.0-py3.8.egg
Copying eth2deposit-0.2.0-py3.8.egg to c:\program files (x86)\python38-32\lib\site-packages
eth2deposit 0.2.0 is already the active version in easy-install.pth

Installed c:\program files (x86)\python38-32\lib\site-packages\eth2deposit-0.2.0-py3.8.egg
Processing dependencies for eth2deposit==0.2.0
Finished processing dependencies for eth2deposit==0.2.0

msc82@DESKTOP-N12G70C MINGW64 /e/eth2.0-deposit-cli (master)
$ sh deposit.sh
msys
Running deposit-cli...
Traceback (most recent call last):
File "./eth2deposit/deposit.py", line 3, in
import click
ModuleNotFoundError: No module named 'click'

msc82@DESKTOP-N12G70C MINGW64 /e/eth2.0-deposit-cli (master)

[ToB Audit] #6: Passwords are accessible via shell history (if passed in as arguments)

Description

The deposit CLI tool allows passwords to be supplied as command-line arguments, enabling password leakage through operating systems, such as terminal shell history and execution of ps or similar commands.

The tool allows specification of a password through command-line arguments:

$ python3 ./eth2deposit/deposit.py --password="mypassword"

However, while accessing the shell history in a terminal window, the password is leaked in
plaintext:

516 python3 ./eth2deposit/deposit.py --password="mypassword"
517 bash history

Exploit Scenario

Alice uses the Deposit-CLI to generate secret keys on her machine with a command line argument --password='12345'. An attacker, Eve gains access to Alice’s machine and looks through previously run commands on the terminal and finds the password used to secure the BLS signing key. In combination with #98, Eve also has access to the sensitive keys stored in the files.

Recommendation

Short term, do not allow users to use the command line argument to specify passwords.
Long term, minimize the usage of sensitive information and ensure secrets are not exposed via operating system logs.

An instructional gap in generate-keys: Option 1

https://medalla.launchpad.ethereum.org/generate-keys

Option 1: Use binary executable file

This step directs a user to download a zip/tarball file from a github release page but does not instruct the user to extract the binary from the zip. Failure to extract the binary causes the next step to fail. Option 1 should include instructions for extracting the zip/tarball. This issue appears consistent across the directions for all three platforms.

[ToB Audit] #3: Deposit does not provide entropy validation on passwords

Description

The deposit cli tool allows users to use weak or even empty passwords, during the generation of keys.
The tool is responsible for generating a BLS key pair. In order to protect the secret keys, the tool uses password-based key derivation functions to securely store the secrets. Therefore, when using the tool, a user should provide a password that will be used to protect these secrets:

@click.password_option(prompt='Type the password that secures your validator keystore(s)')
def main(num_validators: int, mnemonic_language: str, folder: str, chain: str, password: str) -> None:
...
click.echo('Saving your keystore(s).')
keystore_filefolders = credentials.export_keystores(password=password, folder=folder) click.echo('Creating your deposit(s).')
deposits_file = credentials.export_deposit_data_json(folder=folder) click.echo('Verifying your keystore(s).')
assert credentials.verify_keystores(keystore_filefolders=keystore_filefolders,
password=password) ...

However, the Deposit CLI lacks user password validation while generating the mnemonic, which allows weak passwords to be used. This could make an offline dictionary attack possible.
Moreover, when calling the CLI with an optional argument --password='', users are able to generate a mnemonic with a null password. This command line argument is undocumented in the ef-deposit-cli documentation.

Exploit Scenario

Alice uses Deposit-CLI to generate secret keys on her machine using a simple password. An attacker, Eve, tries to access the keystore by brute-forcing commonly used passwords and empty passwords. Once successful, Eve has access to the BLS signing key. This attack is made more feasible due to the fact that Eve also has access to the sensitive keys stored in the saved files, as outlined in #98.

Recommendation

Short term, add a validation check on passwords to ensure minimum length.
Long term, use a password strength library/entropy calculator on user passwords to enforce the use of strong passwords.

`withdrawal_credentials` should include the `BLS_WITHDRAWAL_PREFIX`

Issue

In export_deposit_data_json, the withdrawal_credentials is generated by SHA256(credential.withdrawal_pk): https://github.com/ethereum/eth2.0-deposit-cli/blob/96200d76ae30b966d43e879f21d5d1b4d7455917/eth2deposit/credentials.py#L84
And in the eth2 spec (master branch), it says

withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX
withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:] where withdrawal_pubkey is a BLS pubkey

where BLS_WITHDRAWAL_PREFIX is 0x00

`compute_domain` function doesn't follow the spec definition

Issue

In this repo:
https://github.com/ethereum/eth2.0-deposit-cli/blob/96200d76ae30b966d43e879f21d5d1b4d7455917/eth2deposit/utils/ssz.py#L27-L31

In the spec (v11.2 version on master branch):

def compute_domain(domain_type: DomainType, fork_version: Version=None, genesis_validators_root: Root=None) -> Domain:
    """
    Return the domain for the ``domain_type`` and ``fork_version``.
    """
    if fork_version is None:
        fork_version = GENESIS_FORK_VERSION
    if genesis_validators_root is None:
        genesis_validators_root = Root()  # all bytes zero by default
    fork_data_root = compute_fork_data_root(fork_version, genesis_validators_root)
    return Domain(domain_type + fork_data_root[:28])

How to fix it

I was thinking about importing pyspec (eth2spec) for double-checking the SSZ serialization (#11) but also was hesitating about adding more dependencies and Python 3.8 requirements. However, it would be nice if we could use the helper functions from the spec to avoid this kind of bugs.

Little concern

Okay, first, I am really not an expert, Iam juste testing some stuff out because I plan to stack in ETH 2.0 and I try to understand what Ido.

I was using the Bicornis Sprint release to generate the validator key for the prysm launch pad. The JSON that came out (
Bicornis Sprint.txt
had some difference with the new one that I generated with I'm Zinken this will be the last testnet see file (
zinken.txt
).

I found some differences
For example in the section:
crypto the first file has SCRYPT in function and the new one has sha256

I did a test using ETHDO to regenerate the wallet using the seed phrase of both file. I was not able to regenerate the correct wallet address with ETHDO using the seed phrase that was generated by Bicornis Sprint (scrypt) release.

But it worked fine with the lastest release (sha256)

So if some people generate their withdrawal key and save the mnemonic phrase, how they will know if it was generated using sha256 or scrytp in order to regenerate the correct wallet and account?

Thank you!

Warning when building deposit-cli with native Python

The following warning appears when using pip3 or running the deposit shell install script:

THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    toolz==0.10.0 from https://files.pythonhosted.org/packages/b5/73/977bae1550ff5f6aa4050680339523b045e991e92fa58c4709253332a870/toolz-0.10.0-py3-none-any.whl#sha256=e71d8d91c8902fb7659c23e10e9698a8c5cbea985683b8a378c6fd67b52f2fc4 (from -r requirements.txt (line 61)):
        Expected sha256 08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560
             Got        e71d8d91c8902fb7659c23e10e9698a8c5cbea985683b8a378c6fd67b52f2fc4

Checksums and/or signatures for release binaries?

Are there checksums or signatures available for release files? I haven't been able to find anything of the sort on the releases page.

Including at least a SHA256 checksum for each release file would be a nice courtesy since a lot of people's deposits will be riding on this code.

deposit.sh doesn't work with cygwin

User@Windows /home/user/eth2.0-deposit-cli
$ sh deposit.sh
deposit.sh: line 2: $'\r': command not found
deposit.sh: line 14: syntax error near unexpected token `elif'
deposit.sh: line 14: `elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin"']]; then

🤔

Support generating more keys from the same mnemonic

If a validator has already created a few keys & deposits, it would be useful to allow them to create more from the same mnemonic. The footgun risk is very high here as if users use the same keys twice, they will "top up" their existing validators.

One option is to require users to show their existing keystores before they are allowed to create more deposits.

I am very nervous about enabling this functionality if we can't come up with a clever way of not double depositing.

Related to #27

Custom path range

Suggested by @protolambda

It would be nice to have an option to make keys for a custom path range, i.e., if you already made some deposits, I don't want to recreate the keystores or deposit data. It's also good for error-prone.

[ToB Audit] #2: Deposit stores a world-readable file with sensitive information (file permissions)

Description

The deposit tool saves the keys in world-readable files. This practice is risky and could lead to a compromise.
After generating the key, deposit stores the encrypted keys in a directory that is world-readable by default. Thus, any user with read access to a file’s enclosing directory can get access to the private information. Also note that world read(-only) directory access is a common default on many Unix-based systems.

Exploit Scenario

An attacker learns that the deposit tool was installed on some machine. The attacker gains local access to that machine. With the default directory permissions still in place, the attacker reads the keys from the saved files.

Recommendation

Short term, minimize the permissions when saving sensitive files.
Long term, review the amount of necessary permissions for each component of your system.

ARM binary

I'd like to be able to run this as an ARM binary offline on my Raspberry Pi 4. Could we get them for testnet and mainnet?

Regenerate keys from mnemonic

I was wondering how I can recreate the deposit file and validator keys from the mnemonic - Is this a supported feature?

[ToB Audit] #10: Python Crypto wrappings allow unsafe parameters

Trail of Bits audit report

Description

The Deposit CLI tool uses a variety of cryptographic primitives, such as scrypt, PBKDF2, and AES. In order to include these primitives, the codebase provides wrapper functions around the Python Crypto library. These functions will, for example, take in an input password, salt, and other relevant parameters and pass them into scrypt.

The password-based key derivation functions, scrypt and PBKDF2, are tunable by specific parameters (for example, number of iterations for PBKDF2). These parameters can be adjusted so that these functions are as slow or fast as desired. However, if these parameters are set to low enough values, they can be considered unsafe to use for password storage. Currently, there are no restrictions on any of these parameters that are passed to both scrypt and PBKDF2.

The codebase defines keystores for both scrypt and PBKDF2, which select the parameters for the user, and these parameters are safe. However, it would be safer to wrap both scrypt and PBKDF2 with some basic checks to ensure that the input parameters are not unsafe (e.g., restricting the number of iterations being less than 1000).

Recommendation

Short term, determine which parameters you deem to be unsafe to ever use and add a warning that checks if either scrypt or PBDKF2 are given unsafe parameters.
Long term, consider adding checks that prevent either scrypt or PBKDF2 from being called with unsafe parameters.

Make deposit.sh install docker-friendly

Docker expects exit 0 on success. Simply changing the logic for deposit.sh install to exit 0 after successful install would allow this command to be used in a Dockerfile.

Workaround: Do pip3 and python3 steps manually instead of relying on deposit.sh.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.