commit 3e3d9bd5c3a906136168f8d57933b882a06c3872 Author: Damian Johnson atagar@torproject.org Date: Tue Dec 11 10:16:33 2018 -0800
Descriptor digest example
Waste not, want not. I wrote this demo script for my recent status report (https://blog.atagar.com/november2018/), but on reflection it makes a good example for how to use our new digest methods. --- docs/_static/digest_chart.png | Bin 0 -> 66121 bytes docs/_static/example/check_digests.py | 52 ++++++++++++++++++++++ docs/tutorials/double_double_toil_and_trouble.rst | 5 +++ docs/tutorials/examples/check_digests.rst | 38 ++++++++++++++++ 4 files changed, 95 insertions(+)
diff --git a/docs/_static/digest_chart.png b/docs/_static/digest_chart.png new file mode 100644 index 00000000..0a3dc3d5 Binary files /dev/null and b/docs/_static/digest_chart.png differ diff --git a/docs/_static/example/check_digests.py b/docs/_static/example/check_digests.py new file mode 100644 index 00000000..2be3c368 --- /dev/null +++ b/docs/_static/example/check_digests.py @@ -0,0 +1,52 @@ +import sys + +import stem.descriptor.remote +import stem.util.tor_tools + + +def download_descriptors(fingerprint): + """ + Downloads the descriptors we need to validate this relay. Downloads are + parallelized, providing the caller with a tuple of the form... + + (router_status_entry, server_descriptor, extrainfo_descriptor) + """ + + conensus_query = stem.descriptor.remote.get_consensus() + server_desc_query = stem.descriptor.remote.get_server_descriptors(fingerprint) + extrainfo_query = stem.descriptor.remote.get_extrainfo_descriptors(fingerprint) + + router_status_entries = filter(lambda desc: desc.fingerprint == fingerprint, conensus_query.run()) + + if len(router_status_entries) != 1: + raise IOError("Unable to find relay '%s' in the consensus" % fingerprint) + + return ( + router_status_entries[0], + server_desc_query.run()[0], + extrainfo_query.run()[0], + ) + +if __name__ == '__main__': + fingerprint = raw_input("What relay fingerprint would you like to validate?\n") + print('') # blank line + + if not stem.util.tor_tools.is_valid_fingerprint(fingerprint): + print("'%s' is not a valid relay fingerprint" % fingerprint) + sys.exit(1) + + try: + router_status_entry, server_desc, extrainfo_desc = download_descriptors(fingerprint) + except Exception as exc: + print(exc) + sys.exit(1) + + if router_status_entry.digest == server_desc.digest(): + print("Server descriptor digest is correct") + else: + print("Server descriptor digest invalid, expected %s but is %s" % (router_status_entry.digest, server_desc.digest())) + + if server_desc.extra_info_digest == extrainfo_desc.digest(): + print("Extrainfo descriptor digest is correct") + else: + print("Extrainfo descriptor digest invalid, expected %s but is %s" % (server_desc.extra_info_digest, extrainfo_desc.digest())) diff --git a/docs/tutorials/double_double_toil_and_trouble.rst b/docs/tutorials/double_double_toil_and_trouble.rst index 6701f1dc..c9a63a7b 100644 --- a/docs/tutorials/double_double_toil_and_trouble.rst +++ b/docs/tutorials/double_double_toil_and_trouble.rst @@ -132,3 +132,8 @@ Descriptors
Example for writing a Tor consensus to disk, and reading it back.
+* `Checking Digests <examples/check_digests.html>`_ + + Looking for additional integrity that your descriptor is properly signed? + Digests embedded in parent documents provide transitive validation. + diff --git a/docs/tutorials/examples/check_digests.rst b/docs/tutorials/examples/check_digests.rst new file mode 100644 index 00000000..dc2f0ee8 --- /dev/null +++ b/docs/tutorials/examples/check_digests.rst @@ -0,0 +1,38 @@ +Checking Descriptor Digests +=========================== + +.. image:: /_static/buttons/back.png + :target: ../double_double_toil_and_trouble.html + +Tor relay information is provided by `multiple documents +<../mirror_mirror_on_the_wall.html#what-is-a-descriptor>`_. Signed descriptors +transitively validate others by inclusion of their digest. For example, our +consensus references server descriptor digest, and server descriptors in turn +cite extrainfo digests. + +To illustrate, here’s a diagram from Iain... + +.. image:: /_static/digest_chart.png + +Stem can calculate digests from `server +<../../api/descriptor/server_descriptor.html#stem.descriptor.server_descriptor.ServerDescriptor.digest>`_, +`extrainfo +<../../api/descriptor/extrainfo_descriptor.html#stem.descriptor.extrainfo_descriptor.ExtraInfoDescriptor.digest>`_, +`microdescriptor +<../../api/descriptor/microdescriptor.html#stem.descriptor.microdescriptor.Microdescriptor.digest>`_, +and `consensus documents +<../../api/descriptor/networkstatus.html#stem.descriptor.networkstatus.NetworkStatusDocument.digest>`_. +For instance, to validate an extrainfo descriptor... + +.. literalinclude:: /_static/example/check_digests.py + :language: python + +:: + + % python check_digests.py + What relay fingerprint would you like to validate? + 3BB34C63072D9D10E836EE42968713F7B9325F66 + + Server descriptor digest is correct + Extrainfo descriptor digest is correct +
tor-commits@lists.torproject.org