Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ticket 33675: Adding regex to search microdescriptor files for relay ed25519 keys #62

Closed
34 changes: 31 additions & 3 deletions lib/chutney/TorNet.py
Expand Up @@ -23,6 +23,7 @@
import subprocess
import sys
import time
import base64

from chutney.Debug import debug_flag, debug

Expand Down Expand Up @@ -667,6 +668,7 @@ def preConfig(self, net):
self._genAuthorityKey()
if self._env['relay']:
self._genRouterKey()
self._setEd25519Id()
if self._env['hs']:
self._makeHiddenServiceDir()

Expand Down Expand Up @@ -763,7 +765,32 @@ def _genRouterKey(self):
.format(" ".join(cmdline), stdouterr))
sys.exit(1)
self._env['fingerprint'] = fingerprint


def _setEd25519Id(self):
"""Read the ed25519 identity key for this router, and set up the 'ed25519-id' entry in the Environ"""
datadir = self._env['dir']
key_file = os.path.join(datadir, 'keys', "ed25519_master_id_public_key")
EXPECTED_ED25519_FILE_SIZE = 64
CURRENT_FILE_SIZE = os.stat(key_file).st_size
if not os.path.exists(key_file):
print("File {} does not exist. Are you running a very old tor version?".format(key_file))
return
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
elif CURRENT_FILE_SIZE != EXPECTED_ED25519_FILE_SIZE:
raise ValueError("The current size of the file is {} bytes, which is not matching the expected value of {} bytes".format(CURRENT_FILE_SIZE, EXPECTED_ED25519_FILE_SIZE))
else:
with open(key_file, 'rb') as f:
ED25519_KEY_POSITION = 32
f.seek(ED25519_KEY_POSITION)
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
rest_file = f.read()
encoded_value = base64.b64encode(rest_file)
ed25519_id = encoded_value.decode('utf-8').replace('=', '')
EXPECTED_ED25519_BASE64_KEY_SIZE = 43
CURRENT_ED25519_BASE64_KEY_SIZE = len(ed25519_id)
if CURRENT_ED25519_BASE64_KEY_SIZE != EXPECTED_ED25519_BASE64_KEY_SIZE:
raise ValueError("The current length of the key is {}, which is not matching the expected length of {}".format(CURRENT_ED25519_BASE64_KEY_SIZE, EXPECTED_ED25519_BASE64_KEY_SIZE))
else:
self._env['ed25519_id'] = ed25519_id
teor2345 marked this conversation as resolved.
Show resolved Hide resolved

def _getAltAuthLines(self, hasbridgeauth=False):
"""Return a combination of AlternateDirAuthority,
and AlternateBridgeAuthority lines for
Expand Down Expand Up @@ -1300,6 +1327,7 @@ def getNodeDirInfoStatusPattern(self, dir_format):
the ed25519 key. (Or RSA block matching, which is hard.)
Copy link
Contributor

Choose a reason for hiding this comment

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

More cleanup:

  • The microdesc format is now implemented, so we can delete that comment.
  • We need to explain what returning "None" means for this function. I can make that change. I should have done it when I wrote the function.

"""
nickname = self.getNick()
#ed25519_id = self._setEd25519Id()

teor2345 marked this conversation as resolved.
Show resolved Hide resolved
cons = dir_format in ["ns_cons",
"md_cons",
Expand All @@ -1324,10 +1352,10 @@ def getNodeDirInfoStatusPattern(self, dir_format):
return r'^router ' + nickname + " "
elif md:
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we are only getting None for ed25519_key here. Because we are loading ed25519_id during configure(). But this code is called during wait_for_bootstrap().

Can you help me check what is happening?

If md is True, print the values of nickname and ed25519_key. Then we can check the logs.

# Not yet implemented, see #33428
Copy link
Contributor

Choose a reason for hiding this comment

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

Cleanup: this feature is now implemented, so we can delete this comment.

# r'^id ed25519 " + ed25519_identity (end of line)
return r'^id ed25519 ' + re.escape(ed25519_id)
# needs ed25519-identity from #30642
# or the existing keys/ed25519_master_id_public_key
teor2345 marked this conversation as resolved.
Show resolved Hide resolved
return None


def getFileDirInfoStatus(self, dir_format, dir_path):
"""Check dir_path, a directory path used by another node, to see if
Expand Down