[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [chutney/master] Rewrite ed25519 key loading to be more robust
commit 74a77f68897347053abea73c17e4cb045096c9c9
Author: teor <teor@xxxxxxxxxx>
Date: Mon May 18 14:24:05 2020 +1000
Rewrite ed25519 key loading to be more robust
Tolerate being called early during bootstrap, and being called on old
tor versions without ed25519.
---
lib/chutney/TorNet.py | 83 ++++++++++++++++++++++++++++-----------------------
1 file changed, 46 insertions(+), 37 deletions(-)
diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py
index 2eef368..5d28763 100644
--- a/lib/chutney/TorNet.py
+++ b/lib/chutney/TorNet.py
@@ -866,48 +866,53 @@ class LocalNodeBuilder(NodeBuilder):
class LocalNodeController(NodeController):
- def _setEd25519Id(self):
+ def __init__(self, env):
+ NodeController.__init__(self, env)
+ self._env = env
+
+ def _loadEd25519Id(self):
"""
- Read the ed25519 identity key for this router, and set up the
- 'ed25519_id' entry in the Environ
+ Read the ed25519 identity key for this router, encode it using
+ base64, strip trailing padding, and return it.
+
+ If the file does not exist, returns None.
+
+ Raises a ValueError if the file appears to be corrupt.
"""
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 we're called early during bootstrap, the file won't have been
+ # created yet. (And some very old tor versions don't have ed25519.)
if not os.path.exists(key_file):
- print(("File {} does not exist. "
- "Are you running a very old tor version?").format(key_file))
- return
- 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)
- 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
+ debug(("File {} does not exist. Are you running a very old tor "
+ "version?").format(key_file))
+ return None
- def __init__(self, env):
- NodeController.__init__(self, env)
- self._env = env
- self._setEd25519Id()
+ EXPECTED_ED25519_FILE_SIZE = 64
+ key_file_size = os.stat(key_file).st_size
+ if key_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(key_file_size, EXPECTED_ED25519_FILE_SIZE))
+
+ with open(key_file, 'rb') as f:
+ ED25519_KEY_POSITION = 32
+ f.seek(ED25519_KEY_POSITION)
+ rest_file = f.read()
+ encoded_value = base64.b64encode(rest_file)
+ # tor strips trailing base64 padding
+ ed25519_id = encoded_value.decode('utf-8').replace('=', '')
+ EXPECTED_ED25519_BASE64_KEY_SIZE = 43
+ key_base64_size = len(ed25519_id)
+ if (key_base64_size != EXPECTED_ED25519_BASE64_KEY_SIZE):
+ raise ValueError(
+ ("The current length of the key is {}, which is not "
+ "matching the expected length of {}")
+ .format(key_base64_size,
+ EXPECTED_ED25519_BASE64_KEY_SIZE))
+ return ed25519_id
def getNick(self):
"""Return the nickname for this node."""
@@ -921,11 +926,15 @@ class LocalNodeController(NodeController):
return 0
def getEd25519Id(self):
- """Return the value of ed25519 key"""
+ """Return the base64-encoded ed25519 public key of this node."""
try:
return self._env['ed25519_id']
except KeyError:
- return None
+ ed25519_id = self._loadEd25519Id()
+ # cache a copy for later
+ if ed25519_id:
+ self._env['ed25519_id'] = ed25519_id
+ return ed25519_id
def getBridgeClient(self):
"""Return the bridge client flag for this node."""
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits