-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
Hi,
Tor 0.2.7.x will support Ed25519 router identities along with the traditional 1024-bit RSA ones which will be used simultaneously for some time, until we will completely deprecate RSA router identities.
I would like to document what Tor needs to do (or don't do) by default in some cases to prevent mistakes which confused operators could do. Please review and add/edit/remove if something is wrong, doesn't make sense or is incomplete. When finished, I will split it in more parts and open tickets on trac based on priorities. Some cases are already covered (Tor does what it should by default). We also need to compose the messages Tor will print in the log files in a way that they will be of a reasonable length and expressive/explicit/polite/whatever.
Take in consideration the design: For an Ed25519 identity, Tor will generate these files in $datadirectory/keys:
- - ed25519_master_id_secret_key - the master identity key. Optionally this can be kept offline or encrypted. This is the file one needs in case he wants to restore a relay. Never expires. Sensitive (if reached it will compromise the identity of the relay forever).
- - ed25519_master_id_public_key - the public key. This is the actual router identity which Tor publishes in the descriptors. It is computed from the secret key and it is not sensitive. Never expires.
- - ed25519_signing_secret_key - a temporary signing key. This will be used for circuits (onionskin) encryption. It is valid only temporary for as long as ed25519_signing_cert says so.
- - ed25519_signing_cert - a cert signed by the master ID key (ed25519_master_id_secret_key) attesting that the ed25519_signing_secret_key 'x' is valid for 'n' days/months. The validity period can be configured with the torrc option SigningKeyLifetime 'n' days/weeks/months (default is 30 days).
Also take in consideration that the directory authorities will pin relays with paired RSA-Ed25519 identities and reject them if one changes. For example, if relay A has ID RSA_A & Ed25519_A, and later changes to RSA_B & Ed25519_A or RSA_A & Ed25519_B, it will be rejected.
The text is also available on Etherpad: https://etherpad.mozilla.org/efIBq6nDwt - ------------------------------------------------------ Ed25519 router identity - default behavior - ------------------------------------------------------ We don't touch the RSA ID key behavior. We let it as it was, use it if secret ID file is there, generate new one if not. The behavior below should be implemented by taking in consideration only the ed25519_* files in $datadirectory/keys (should not care or notice the RSA related files). We don't say anything about offline Ed25519 ID keys or encrypted Ed25519 ID keys. Whoever wants to use these features will have to read the FAQ first and understand some things.
The default is: generate ed25519_master_id_secret_key (unencrypted) in $datadirectory/keys and use that forever, by automatically renewing ed25519_signing_secret_key and ed25519_signing_cert with the default validity period of 30 days, unless otherwise specified in torrc. This is already implemented and it is how Tor works now.
At every start, restart, reload, server reboot, signal sent by user or another app, etc. Tor should: 1) check if file ed25519_master_id_secret_key exists in $datadirectory/keys and it's a valid curve25519 private key file; 2) check if file ed25519_master_id_secret_key_encrypted exists in $datadirectory/keys; 3) check if file ed25519_master_id_public_key exists in $datadirectory/keys and it's a valid curve25519 public key file; 4) check if file ed25519_signing_cert exists in $datadirectory/keys; 5) check if ed25519_signing_cert in $datadirectory/keys is expired; 6) check if ed25519_signing_cert correlates with ed25519_master_id_public_key; 7) check if file ed25519_signing_secret_key exists in $datadirectory/keys; 8) check if ed25519_signing_secret_key correlates with ed25519_signing_cert (non-expired cert refers to that signing key);
1. If ed25519_master_id_secret_key && ed25519_master_id_public_key && ed25519_signing_secret_key && ed25519_signing_cert are all missing from $datadirectory/keys:
- -> We assume it's a new relay or a relay which just upgraded to a Tor that supports Ed25519 router identities. Generate a new Ed25519 identity unencrypted (ed25519_master_id_secret_key, ed25519_master_id_public_key, ed25519_signing_secret_key and ed25519_signing_cert with a validity for 30 days unless specified otherwise in torrc) and publish a descriptor using that, proceed as normal after.
2. If ed25519_master_id_secret_key is missing or exists encrypted && ed25519_master_id_public_key exists in $datadirectory/keys and ed25519_signing_secret_key and ed25519_signing_cert are expired:
- -> We assume this can happen suddenly, while running unattended. Disable relay functionality and stop publishing descriptors (close ORPort and (if open) DirPort). Leave client functionality since that could be used by something else on that machine and it shouldn't be affected. Print warnings in the log file that action is required (generate new ed25519_signing_secret_key and ed25519_signing_cert or move the ed25519_master_id_secret_key unencrypted in $datadirectory/keys so Tor can do this by itself). The operator needs to signal Tor with a reload signal (HUP) or restart/stop & start after completing the action. Tor will check for the valid ed25519_signing_secret_key and ed25519_signing_cert by itself every time server restarts (along with Tor process) or at every automated reload signal (HUP).
3. If ed25519_master_id_secret_key exists unencrypted in $datadirectory/keys and there is no ed25519_master_id_public_key, ed25519_signing_secret_key or ed25519_signing_cert (or ed25519_signing_secret_key and ed25519_signing_cert are expired):
- -> We assume the relay has just been restored and the Ed25519 identity was backed up. Automatically generate ed25519_master_id_public_key, ed25519_signing_secret_key and ed25519_signing_cert with a validity period of 30 days (unless otherwise specified in torrc). - -> Since we have the ed25519_master_id_secret_key unencrypted, and at startup we always check for availability/validity of the other ed25519* files by default anyway, we should generate automatically in this case: ed25519_master_id_public_key (if missing), ed25519_signing_secret_key (if missing or expired) and ed25519_signing_cert (if missing or expired).
4. If ed25519_master_id_secret_key exists encrypted in $datadirectory/keys && there is no ed25519_master_id_public_key, ed25519_signing_secret_key or ed25519_signing_cert (even if just one of these 3 is missing):
- -> We assume the relay identity existed previously and ed25519_master_id_secret_key_encrypted was restored form a backup. Do not start Tor at all and print explicit warnings that action is required - Tor cannot decrypt the ed25519_master_id_secret_key_encrypted file. Generate ed25519_master_id_public_key, ed25519_signing_secret_key and ed25519_signing_cert or decrypt the ed25519_master_id_secret_key_encrypted in $datadirectory/keys so Tor can do it by itself.
5. If the chain validation fails (ed25519_signing_cert doesn't correlate to ed25519_master_id_public_key AND/OR ed25519_signing_secret_key doesn't correlate to ed25519_signing_cert):
- -> We assume the operator probably runs many relays and holds many ed25519_master_id_secret_key files maybe accidentally mixes them and generates temporary signing key and key cert using the master key from another relay. Do no start Tor service at all and print warnings: the ed25519_signing_secret_key and ed25519_signing_cert are generated with the ed25519_master_id_secret_key of another relay. These files should be removed and replaced with the correct ones (search for the ed25519_master_id_secret_key which belongs to this relay). Otherwise it's useless (since we already reject RSA-Ed25519 which don't match), if the ed25519_master_id_secret_key is lost permanently, nothing else for the operator to do but to manually generate fresh identity both RSA and Ed25519 so the relay can be part of the consensus (start from scratch).
6. If ed25519_master_id_secret_key is missing or _encrypted AND ed25519_master_id_public_key is also missing from $datadirectory/keys AND a) we have an ed25519_signing_secret_key and ed25519_signing_cert which are not expired:
- ->Automatically compute ed25519_master_public_key from the ed25519_signing_cert and save it in $datadirectory/keys.
b) if ed25519_signing_secret_key and ed25519_signing_cert are expired:
- ->Do no start Tor service at all and print warnings that user action is required (generate new ed25519_signing_secret_key and ed25519_signing_cert or move the ed25519_master_id_secret_key unencrypted in $datadirectory/keys so Tor can do this by itself). The operator needs to signal Tor with a reload signal (HUP) or restart/stop & start after completing the action. Tor will check for the valid ed25519_signing_secret_key and ed25519_signing_cert by itself every time server restarts (along with Tor process) or at every automated reload signal (HUP).
- ------------------------------------------------------ Commands related to Ed25519 keys - ------------------------------------------------------ 1. tor --keygen should be replaced with tor --ecckeygen (keygen is not explicit enough since we are talking about 2 router identities which are used simultaneously [RSA and Ed25519]). - - Ask if user wants to encrypt the key with a passphrase and if yes ask 2 passphrase confirmations. Only allow ASCII, check and return invalid passphrase otherwise (local language keyboards mess things up). I suggest the Encrypt key? question [y/N] should be a No by default. - - Unless user specifies --out /path/to/dir to save the output files, save them in working directory (where the command is run). Do not create the folder and save them in $HOME/.tor. - - Only generate an ed25519_master_id_secret_key with this command (no ed25519_master_id_public_key, ed25519_signing_secret_key or ed25519_signing_cert). Print a message confirming this: ed25519_master_id_secret_key was successfully generated and saved encrypted/unencrypted (depending how it was generated) in $location ($location = either working directory where the command was run either the location specified separately with --out argument included in the - --ecckeygen command). Append _encrypted at the end of the file name in case a passphrase was provided.
2. tor --encryptkey <ed25519_master_id_secret_key file> or /path/to/<key file> - - check if it's a valid ed25519_master_id_secret_key unencrypted, ask for 2 passphrase confirmations and encrypt it. Only allow ASCII, check and return invalid passphrase otherwise (local language keyboards mess things up). - - ask if the user wants to delete the old plaintext ed25519_master_id_secret_key and only remain with the encrypted copy. [Y/n], Yes by default. Delete it in a secure way if yes, obviously. - - save the encrypted key in the working directory where the command is run or with an argument --out /path/to/dir. Print a message confirming this: ed25519_master_id_secret_key was successfully encrypted and saved in $location ($location = either working directory where the command was run either the location specified separately with --out argument included in the --encryptkey command).
3. tor --decryptkey <ed25519_master_id_secret_key file> or /path/to/<key file> - - ask for confirmation: Are you sure you wan to decrypt your ed25519_master_id_secret_key? This will save the master ID key in plaintext, not protected by a passphrase. [Y/n], Yes by default. - - ask for the passphrase and decrypt. - - ask if the user wants to delete the old encrypted ed25519_master_id_secret_key and only remain with the unencrypted copy of it. [y/N], No by default. - - save the plaintext key in the working directory where the command is run or with an argument --out /path/to/dir. Print a message confirming this: ed25519_master_id_secret_key was successfully decrypted permanently and saved in $location ($location = either working directory where the command was run either the location specified separately with --out argument included in the --decryptkey command).
4. tor --newpasskey <ed25519_master_id_secret_key file> or /path/to/<key file> - - ask for the current passphrase. - - ask for the new passphrase 2 times. Only allow ASCII, check and return invalid passphrase otherwise (local language keyboards mess things up). - - update the ed25519_master_id_secret_key file with then new passphrase in place, don't save a separate new copy with this command. - - print a message confirming that the passphrase has been successfully and permanently changed.
5. tor --gensignkey <ed25519_master_id_secret_key file> or /path/to/<key file> - - ask for the passphrase if key file is encrypted. - - generate new ed25519_signing_secret_key and ed25519_signing_cert valid for 30 days unless specified otherwise in torrc. If there is a SigningKeyLifetime in torrc, read it and ask the user: The signing key lifetime in your torrc is n days/weeks/months, use this validity period? [Y/n], yes default. If user enters N, ask the user to manually enter the lifetime. - - save the output files in the working directory where the command is run or with an argument --out /path/to/dir. Print a message which explains that these files need to be moved in Tor's $datadirectory/keys. - - Print a message confirming this: ed25519_master_id_public_key, ed25519_signing_secret_key and ed25519_signing_cert with a validity period of $validity have been successfully created and saved in $location. Please move them to your Tor $datadirectory/keys folder and make sure Tor can access/read them. ($validity = SigningKeyLifetime in torrc or lifetime manually specified by the user or 30 days, the default if there is no torrc setting for this and no input from the user; $location = either working directory where the command was run either the location specified separately with --out argument included in the --gensignkey command).
6. tor --getpubkey <ed25519_master_id_secret_key file> or /path/to/<key file> - - ask for the passphrase if key file is encrypted - - compute the ed2551_master_id_public_key - - save the output file ed25519_master_id_public_key in working directory where the command is run or with an argument --out /path/to/dir. - - Print a message confirming that the ed25519_master_id_public_key has been saved in $location ($location = either working directory where the command was run either the location specified separately with - --out argument included in the --getpubkey command).
- ------------------------------------------------------ Permissions - a thing many users don't know/care about: - - If Tor cannot complete a command from above because it does not have permission to read the ed25519_master_id_secret_key print an error message and instruct the user that he should run the tor command as the rightful user or change permissions over the ed25519_master_id_secret_key file. - - If Tor cannot save the output files resulted from a command because it does not have write permissions in the working directory where the command is run or the destination directory manually specified with - --out argument included in command print an error message and instruct the user that he should either run the tor command as the rightful user or select a destination directory where current user has write permissions. - - Always save the output files when using above commands with the correct permissions (I guess these are chmod 0600?). - - Can Tor work if the files in $datadirectory/keys folder are owned by other user than the one running Tor? If not, we should try to detect what user runs Tor on that system (not everywhere Tor runs under debian-tor, in FreeBSD it is _tor for example) and change the owner of the files after they are generated and saved.