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 contentRaises: 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 attributesRaises: ValueError if the address, port, or keys are malformed
-
static
create_for_link_specifiers
(link_specifiers, expiration=None, onion_key=None, enc_key=None, auth_key=None, signing_key=None)[source]¶ 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 attributesRaises: 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
- link_specifiers (list) –
-
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
subclassRaises: - 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
subclassRaises: - 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
andInnerLayer
).Parameters: onion_address (str) – hidden service address this descriptor is from
Returns: InnerLayer
with our decrypted contentRaises: - 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
subclassRaises: - 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: - outer (stem.descriptor.hidden_service.OuterLayer) – enclosing encryption layer
- formats (list) – * recognized CREATE2 cell formats
- intro_auth (list) – * introduction-layer authentication types
- is_single_service (bool) – * True if this is a single onion service, False otherwise
- introduction_points (list) –
IntroductionPointV3
where this service is reachable
* 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
subclassRaises: - 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