torproject / stem

Python controller library for Tor
https://stem.torproject.org/
GNU Lesser General Public License v3.0
280 stars 76 forks source link

get_hidden_service_descriptor doesn't give a v3 descriptor #96

Open atagar opened 3 years ago

atagar commented 3 years ago

Stem's get_hidden_service_descriptor method can only retrieve v2 descriptors. Tor's HSFETCH added v3 support and Stem can parse v3 descriptors.

We should look into adding v3 support to the get_hidden_service_descriptor method.

atagar commented 3 years ago

Oh crap! My bad. On reflection since HSFETCH transparently works with v3 addresses and we go through the hidden_service's parse_file() method it looks like this already works. It's just a documentation and type hint fix.

atagar commented 3 years ago

I just double checked and yup, v3 works...

from stem.control import Controller

hs_address = 'jamie3vkiwibfiwucd6vxijskbhpjdyajmzeor4mc4i7yopvpo4p7cyd'

with Controller.from_port() as controller:
  controller.authenticate()
  print(controller.get_hidden_service_descriptor(hs_address))
% python demo.py 
hs-descriptor 3
descriptor-lifetime 180
descriptor-signing-key-cert
-----BEGIN ED25519 CERT-----
AQgABtzLAarUntf8SWwGyISIuPimU/DMpNSRhpY1B89ng3lk+qGpAQAgBACy/m0a
njtbQIsFvTulLeEJpx8XJhPppYbKNuE3qoa5AdiHacO7a+QZlz6Km2fvkftv4Hzh
2o9y8af1AwyGBWu8+BNCDeZy9UikdGQ/4Xr6L6jNeq0b9hn2hko0O7WvdA8=
-----END ED25519 CERT-----
revision-counter 2441650557
superencrypted
-----BEGIN MESSAGE-----
ADWK6fzIy4FMUuZqPJXV3A+6BM90LOIRS0JpBNw9frMeQ3SrBZWYU91o5iv9rvTs
/hoHCTXXEoXMm9m2PfeqCPXQ10i8DlEU2KWOCGMSgbhC5XBc+6DH/kSddHQpmYRE
...
atagar commented 2 years ago

Oops, a good catch from Zanella. Our get_hidden_service_descriptor method always provides a HiddenServiceDescriptorV2 object, even if we fetch a v3 descriptor. As a result none the attributes and decrypt method are unavailable.

You can work around this by re-casting the descriptor to be v3 as demonstrated below but this is clearly a bug.

from stem.control import Controller
from stem.descriptor.hidden_service import HiddenServiceDescriptorV3

hs_address = 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad'

with Controller.from_port() as controller:
  controller.authenticate()
  desc = controller.get_hidden_service_descriptor(hs_address)  # mistakenly a HSv2 descriptor

  desc = HiddenServiceDescriptorV3.from_str(str(desc))  # reparse as HSv3
  print(desc.decrypt(hs_address))
% python demo.py 
create2-formats 2
single-onion-service
introduction-point AwAGBU9PhQG7AhTQedaBiSZoTFl5wYFx+xiGKkpXkgMgrdXXiaF5xMfwqN/DAku/4xLnD76R/GpX1jVqoj9BwE4=
onion-key ntor PjkfSiy4fTfOMsmvmWCi354KIpblSkx+NLckhiHAMmA=
auth-key
-----BEGIN ED25519 CERT-----
AQkABvJzAdaXk/sl0u1zOYSYVNkbnDDwiPWmML29DOhOC3mY6dnoAQAgBABYw6hG
/Veqwtja4D+ivGK3xWSTiqdHCvaKlVzd8dCRo/2Srdg+uja7Y2ZLvxeQRb1uvbPs