Stem Docs

Hidden Service Descriptor

Hidden Service Descriptor

Parsing for Tor hidden service descriptors as described in Tor’s version 2 and version 3 rend-spec.

Unlike other descriptor types these describe a hidden service rather than a relay. They’re created by the service, and can only be fetched via relays with the HSDir flag.

These are only available through the Controller’s get_hidden_service_descriptor() method.

Module Overview:

BaseHiddenServiceDescriptor - Common parent for hidden service descriptors
  |- HiddenServiceDescriptorV2 - Version 2 hidden service descriptor
  +- HiddenServiceDescriptorV3 - Version 3 hidden service descriptor
       |- address_from_identity_key - convert an identity key to address
       |- identity_key_from_address - convert an address to identity key
       +- decrypt - decrypt and parse encrypted layers

OuterLayer - First encrypted layer of a hidden service v3 descriptor
InnerLayer - Second encrypted layer of a hidden service v3 descriptor

New in version 1.4.0.

exception stem.descriptor.hidden_service.DecryptionFailure[source]

Bases: Exception

Failure to decrypt the hidden service descriptor’s introduction-points.

class stem.descriptor.hidden_service.IntroductionPoints[source]

Bases: stem.descriptor.hidden_service.IntroductionPoints

Introduction point for a v2 hidden service.

Variables
  • identifier (str) – hash of this introduction point’s identity key

  • address (str) – address of this introduction point

  • port (int) – port where this introduction point is listening

  • onion_key (str) – public key for communicating with this introduction point

  • service_key (str) – public key for communicating with this hidden service

  • intro_authentication (list) – tuples of the form (auth_type, auth_data) for establishing a connection

class stem.descriptor.hidden_service.IntroductionPointV3[source]

Bases: stem.descriptor.hidden_service.IntroductionPointV3

Introduction point for a v3 hidden service.

New in version 1.8.0.

Variables
  • link_specifiers (list) – LinkSpecifier where this service is reachable

  • onion_key_raw (unicode) – base64 ntor introduction point public key

  • auth_key_cert (stem.descriptor.certificate.Ed25519Certificate) – cross-certifier of the signing key with the auth key

  • enc_key_raw (unicode) – base64 introduction request encryption key

  • enc_key_cert (stem.descriptor.certificate.Ed25519Certificate) – cross-certifier of the signing key by the encryption key

  • legacy_key_raw (str) – base64 legacy introduction point RSA public key

  • legacy_key_cert (str) – base64 cross-certifier of the signing key by the legacy key

static parse(content)[source]

Parses an introduction point from its descriptor content.

Parameters

content (str) – descriptor content to parse

Returns

IntroductionPointV3 for the descriptor content

Raises

ValueError if descriptor content is malformed

static create_for_address(address, port, expiration=None, onion_key=None, enc_key=None, auth_key=None, signing_key=None)[source]

Simplified constructor for a single address/port link specifier.

Parameters
  • address (str) – IPv4 or IPv6 address where the service is reachable

  • port (int) – port where the service is reachable

  • expiration (datetime.datetime) – when certificates should expire

  • onion_key (str) – encoded, X25519PublicKey, or X25519PrivateKey onion key

  • enc_key (str) – encoded, X25519PublicKey, or X25519PrivateKey encryption key

  • auth_key (str) – encoded, Ed25519PublicKey, or Ed25519PrivateKey authentication key

  • signing_key (cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey) – service signing key

Returns

IntroductionPointV3 with these attributes

Raises

ValueError if the address, port, or keys are malformed

Simplified constructor. For more sophisticated use cases you can use this as a template for how introduction points are properly created.

Parameters
  • link_specifiers (list) – series of stem.client.datatype.LinkSpecifier where the service is reachable

  • expiration (datetime.datetime) – when certificates should expire

  • onion_key (str) – encoded, X25519PublicKey, or X25519PrivateKey onion key

  • enc_key (str) – encoded, X25519PublicKey, or X25519PrivateKey encryption key

  • auth_key (str) – encoded, Ed25519PublicKey, or Ed25519PrivateKey authentication key

  • signing_key (cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey) – service signing key

Returns

IntroductionPointV3 with these attributes

Raises

ValueError if the address, port, or keys are malformed

encode()[source]

Descriptor representation of this introduction point.

Returns

str for our descriptor representation

onion_key()[source]

Provides our ntor introduction point public key.

Returns

ntor X25519PublicKey

Raises
  • ImportError if required the cryptography module is unavailable

  • EnvironmentError if OpenSSL x25519 unsupported

auth_key()[source]

Provides our authentication certificate’s public key.

Returns

Ed25519PublicKey

Raises
  • ImportError if required the cryptography module is unavailable

  • EnvironmentError if OpenSSL x25519 unsupported

enc_key()[source]

Provides our encryption key.

Returns

encryption X25519PublicKey

Raises
  • ImportError if required the cryptography module is unavailable

  • EnvironmentError if OpenSSL x25519 unsupported

legacy_key()[source]

Provides our legacy introduction point public key.

Returns

legacy X25519PublicKey

Raises
  • ImportError if required the cryptography module is unavailable

  • EnvironmentError if OpenSSL x25519 unsupported

class stem.descriptor.hidden_service.AuthorizedClient(id=None, iv=None, cookie=None)[source]

Bases: object

Client authorized to use a v3 hidden service.

New in version 1.8.0.

Variables
  • id (str) – base64 encoded client id

  • iv (str) – base64 encoded randomized initialization vector

  • cookie (str) – base64 encoded authentication cookie

class stem.descriptor.hidden_service.BaseHiddenServiceDescriptor(contents, lazy_load=False)[source]

Bases: stem.descriptor.Descriptor

Hidden service descriptor.

New in version 1.8.0.

class stem.descriptor.hidden_service.HiddenServiceDescriptorV2(raw_contents, validate=False, skip_crypto_validation=False)[source]

Bases: stem.descriptor.hidden_service.BaseHiddenServiceDescriptor

Version 2 hidden service descriptor.

Variables
  • descriptor_id (str) – * identifier for this descriptor, this is a base32 hash of several fields

  • version (int) – * hidden service descriptor version

  • permanent_key (str) – * long term key of the hidden service

  • secret_id_part (str) – * hash of the time period, cookie, and replica values so our descriptor_id can be validated

  • published (datetime) – * time in UTC when this descriptor was made

  • protocol_versions (list) – * list of int versions that are supported when establishing a connection

  • introduction_points_encoded (str) – raw introduction points blob

  • introduction_points_auth (list) – * tuples of the form (auth_method, auth_data) for our introduction_points_content (deprecated, always [])

  • introduction_points_content (bytes) – decoded introduction-points content without authentication data, if using cookie authentication this is encrypted

  • signature (str) – signature of the descriptor content

* attribute is either required when we’re parsed with validation or has a default value, others are left as None if undefined

Changed in version 1.6.0: Moved from the deprecated pycrypto module to cryptography for validating signatures.

Changed in version 1.6.0: Added the skip_crypto_validation constructor argument.

TYPE_ANNOTATION_NAME = 'hidden-service-descriptor'
classmethod content(attr=None, exclude=(), sign=False)[source]

Creates descriptor content with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

str with the content of a descriptor

Raises
  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

classmethod create(attr=None, exclude=(), validate=True, sign=False)[source]

Creates a descriptor with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • validate (bool) – checks the validity of the descriptor’s content if True, skips these checks otherwise

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

Descriptor subclass

Raises
  • ValueError if the contents is malformed and validate is True

  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

introduction_points[source]

Provided this service’s introduction points.

Returns

list of IntroductionPoints

Raises
  • ValueError if the our introduction-points is malformed

  • DecryptionFailure if unable to decrypt this field

class stem.descriptor.hidden_service.HiddenServiceDescriptorV3(raw_contents, validate=False)[source]

Bases: stem.descriptor.hidden_service.BaseHiddenServiceDescriptor

Version 3 hidden service descriptor.

Variables
  • version (int) – * hidden service descriptor version

  • lifetime (int) – * minutes after publication this descriptor is valid

  • signing_cert (stem.descriptor.certificate.Ed25519Certificate) – * cross-certifier for the short-term descriptor signing key

  • revision_counter (int) – * descriptor revision number

  • superencrypted (str) – * encrypted HS-DESC-ENC payload

  • signature (str) – * signature of this descriptor

* attribute is either required when we’re parsed with validation or has a default value, others are left as None if undefined

New in version 1.8.0.

TYPE_ANNOTATION_NAME = 'hidden-service-descriptor-3'
classmethod content(attr=None, exclude=(), sign=False, inner_layer=None, outer_layer=None, identity_key=None, signing_key=None, signing_cert=None, revision_counter=None, blinding_nonce=None)[source]

Hidden service v3 descriptors consist of three parts:

  • InnerLayer, which most notably contain introduction points where the service can be reached.

  • OuterLayer, which encrypts the InnerLayer among other paremters.

  • HiddenServiceDescriptorV3, which contains the OuterLayer and plaintext parameters.

Construction through this method can supply any or none of these, with omitted parameters populated with randomized defaults.

Ed25519 key blinding adds an additional ~20 ms, and as such is disabled by default. To blind with a random nonce simply call…

HiddenServiceDescriptorV3.create(blinding_nonce = os.urandom(32))
Parameters
  • attr (dict) – keyword/value mappings to be included in plaintext descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • sign (bool) – includes cryptographic signatures and digests if True

  • inner_layer (stem.descriptor.hidden_service.InnerLayer) – inner encrypted layer

  • outer_layer (stem.descriptor.hidden_service.OuterLayer) – outer encrypted layer

:param cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey

identity_key: service identity key

:param cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey

signing_key: service signing key

Parameters
  • signing_cert (stem.descriptor.Ed25519CertificateV1) – certificate signing this descriptor

  • revision_counter (int) – descriptor revision number

  • blinding_nonce (bytes) – 32 byte blinding factor to derive the blinding key

Returns

str with the content of a descriptor

Raises
  • ValueError if parameters are malformed

  • ImportError if cryptography is unavailable

classmethod create(attr=None, exclude=(), validate=True, sign=False, inner_layer=None, outer_layer=None, identity_key=None, signing_key=None, signing_cert=None, revision_counter=None, blinding_nonce=None)[source]

Creates a descriptor with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • validate (bool) – checks the validity of the descriptor’s content if True, skips these checks otherwise

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

Descriptor subclass

Raises
  • ValueError if the contents is malformed and validate is True

  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

decrypt(onion_address)[source]

Decrypt this descriptor. Hidden serice descriptors contain two encryption layers (OuterLayer and InnerLayer).

Parameters

onion_address (str) – hidden service address this descriptor is from

Returns

InnerLayer with our decrypted content

Raises
  • ImportError if required cryptography or sha3 module is unavailable

  • ValueError if unable to decrypt or validation fails

static address_from_identity_key(key, suffix=True)[source]

Converts a hidden service identity key into its address. This accepts all key formats (private, public, or public bytes).

Parameters
  • key (Ed25519PublicKey,Ed25519PrivateKey,bytes) – hidden service identity key

  • suffix (bool) – includes the ‘.onion’ suffix if true, excluded otherwise

Returns

unicode hidden service address

Raises

ImportError if sha3 unsupported

static identity_key_from_address(onion_address)[source]

Converts a hidden service address into its public identity key.

Parameters

onion_address (str) – hidden service address

Returns

bytes for the hidden service’s public identity key

Raises
  • ImportError if sha3 unsupported

  • ValueError if address malformed or checksum is invalid

class stem.descriptor.hidden_service.OuterLayer(content, validate=False)[source]

Bases: stem.descriptor.Descriptor

Initial encryped layer of a hidden service v3 descriptor (spec).

New in version 1.8.0.

Variables
  • auth_type (str) – * encryption scheme used for descriptor authorization

  • ephemeral_key (str) – * base64 encoded x25519 public key

  • clients (dict) – * mapping of authorized client ids to their AuthorizedClient

  • encrypted (str) – * encrypted descriptor inner layer

* attribute is either required when we’re parsed with validation or has a default value, others are left as None if undefined

classmethod content(attr=None, exclude=(), validate=True, sign=False, inner_layer=None, revision_counter=None, authorized_clients=None, subcredential=None, blinded_key=None)[source]

Creates descriptor content with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

str with the content of a descriptor

Raises
  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

classmethod create(attr=None, exclude=(), validate=True, sign=False, inner_layer=None, revision_counter=None, authorized_clients=None, subcredential=None, blinded_key=None)[source]

Creates a descriptor with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • validate (bool) – checks the validity of the descriptor’s content if True, skips these checks otherwise

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

Descriptor subclass

Raises
  • ValueError if the contents is malformed and validate is True

  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

class stem.descriptor.hidden_service.InnerLayer(content, validate=False, outer_layer=None)[source]

Bases: stem.descriptor.Descriptor

Second encryped layer of a hidden service v3 descriptor (spec).

New in version 1.8.0.

Variables

* attribute is either required when we’re parsed with validation or has a default value, others are left as None if undefined

classmethod content(attr=None, exclude=(), sign=False, introduction_points=None)[source]

Creates descriptor content with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

str with the content of a descriptor

Raises
  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

classmethod create(attr=None, exclude=(), validate=True, sign=False, introduction_points=None)[source]

Creates a descriptor with the given attributes. Mandatory fields are filled with dummy information unless data is supplied. This doesn’t yet create a valid signature.

New in version 1.6.0.

Parameters
  • attr (dict) – keyword/value mappings to be included in the descriptor

  • exclude (list) – mandatory keywords to exclude from the descriptor, this results in an invalid descriptor

  • validate (bool) – checks the validity of the descriptor’s content if True, skips these checks otherwise

  • sign (bool) – includes cryptographic signatures and digests if True

Returns

Descriptor subclass

Raises
  • ValueError if the contents is malformed and validate is True

  • ImportError if cryptography is unavailable and sign is True

  • NotImplementedError if not implemented for this descriptor type

stem.descriptor.hidden_service.HiddenServiceDescriptor

alias of stem.descriptor.hidden_service.HiddenServiceDescriptorV2