Tor Metrics
  • Metrics
  • Home
  • Users
  • Servers
  • Traffic
  • Performance
  • Onion Services
  • Applications
  • More
  • News
  • Sources
  • Services
  • Development
  • Research
  • About
Tor Metrics
  • Home
  • Users
  • Servers
  • Traffic
  • Performance
  • Onion Services
  • Applications
  • Home
  • Sources
  • Tor Bridge Descriptors

Tor bridge descriptors

1. Purpose of this document

Bridges and the bridge authority publish bridge descriptors that are used by censored clients to connect to the network. We aim for publishing all network directory data for informational and statistical purposes. We cannot, however, make bridge descriptors publicly available in the same way as we publish relay descriptors, because that would defeat the purpose of making bridges hard to enumerate for censors. We therefore sanitize bridge descriptors by removing all potentially identifying information and then publish sanitized versions.

The purpose of this document is to specify the document format of sanitized bridge descriptors. These descriptors are based on original, non-sanitized bridge descriptors after sanitizing any parts that would make it easier to enumerate bridges. Unless stated otherwise, the document meta-format of the Tor directory protocol, version 3 is used.

2. Changes

Sanitization has changed several times over the years. The following list contains all major changes that resulted in raising the "@type" annotation of a descriptor:

  • May 30, 2012: "@type" annotations were first added to sanitized descriptors to indicate descriptor type and version: "@type bridge-server-descriptor 1.0", "@type bridge-extra-info 1.0", and "@type bridge-network-status 1.0".
  • June 29, 2012: "@type bridge-extra-info 1.1" added sanitized "transport" lines.
  • February 1, 2013: "@type bridge-extra-info 1.2" was supposed to indicate added "ntor-onion-key" lines, but those changes only affected bridge server descriptors, not extra-info descriptors. So, nothing has changed as compared to "@type bridge-extra-info 1.1", and there may be "@type bridge-server-descriptor 1.0" descriptors with and without those lines.
  • June 19, 2015: "@type bridge-server-descriptor 1.1" and "@type bridge-extra-info 1.3" added "master-key-ed25519" and "router-digest-sha256" lines to descriptors published by bridges using an ed25519 master key.
  • September 18, 2016: "@type bridge-server-descriptor 1.2" and "@type bridge-network-status 1.1" introduced sanitized TCP ports.
  • July 10, 2017: "@type bridge-network-status 1.2" introduced the "fingerprint" line, containing the fingerprint of the bridge authority which produced the document, to the header.

3. Sanitizing potentially sensitive descriptor items

The following sanitizing steps are applied to original, non-sanitized bridge descriptors.

3.1. Prefix with @type annotation

"@type" SP DescriptorType SP Version

  • DescriptorType is a fixed string that identifies the sanitized bridge descriptor type. Known strings are listed in the sections below.
  • Version is set by the sanitizer to indicate changes in the sanitizing process. The version string consist of a major version number for backward-incompatible changes and a minor version number for backward-compatible changes.

3.2. Replace RSA fingerprints

HashedFingerprint = SHA1(Fingerprint)

  • Fingerprint is the decoded binary representation of the SHA-1 hash of an ASN.1 encoded RSA public key.
  • The (non-sanitized) Fingerprint of a bridge could, in theory, be used quite easily to uniquely identify the bridge. However, clients can request a bridge's current descriptor by sending its Fingerprint to the bridge authority. This is a feature to make bridges on dynamic IP addresses more useful, but it would also allow for trivial enumeration of bridges. Therefore, the original Fingerprint (and anything that could be used to derive it) is removed from descriptors and replaced with something else that can be used to uniquely identify the bridge. The approach taken here is to replace the Fingerprint with its SHA-1 hash.

3.3. Replace ed25519 master keys

HashedMasterKeyEd25519 = SHA256(MasterKeyEd25519)

  • MasterKeyEd25519 is the decoded binary representation of an ed25519 master key.
  • Similar to (non-sanitized) RSA fingerprints (Section 3.2), ed25519 master keys could be used to uniquely identify bridges and to request a current descriptor from the bridge authority. That is why they are replaced with their SHA-256 hashes. In cases where a descriptor only contains an ed25519 certificate and no ed25519 master key, the (non-sanitized) master key is first extracted from the certificate before sanitizing it.

3.4. Remove public keys, certificates, and signatures

[Removed.]

  • Some of the public keys and certificates could be used to derive key fingerprints, hence they need to be replaced or removed. However, replacing them seemed unnecessary and overly complex with respect to keeping state on the sanitizing host. That is why most public keys, certificates, and signatures are simply removed in the sanitizing process.

3.5. Replace IPv4 addresses

SanitizedIpv4Address = "10." | KeyedHash

KeyedHash = SHA256(Ipv4Address | Fingerprint | Secret)[:3]

  • Address is the 4-byte long binary representation of the (non-sanitized) IPv4 address.
  • Fingerprint is the 20-byte long binary representation of the (non-sanitized) long-term identity fingerprint.
  • Secret is a 31-byte long secure random string that changes once per month for all descriptors and statuses published in that month.
  • The [:3] operator picks the first three bytes from the left of the result and encodes it as three dot-separated decimal numbers.
  • Sanitizing IPv4 addresses is obviously required to prevent enumeration of bridges. The approach taken is here is to replace IPv4 addresses with syntactical valid addresses in the private IPv4 address space 10/8 based on a keyed hash function that produces the same sanitized address for a given bridge, IPv4 address, and month.

3.6. Replace IPv6 addresses

SanitizedIpv6Address = "[fd9f:2e19:3bcf::" | KeyedHash | "]"

KeyedHash = SHA256(Ipv6Address | Fingerprint | Secret)[:3]

  • Address is the 16-byte long binary representation of the (non-sanitized) IPv6 address.
  • Fingerprint is the 20-byte long binary representation of the (non-sanitized) long-term identity fingerprint.
  • Secret is a 19-byte long secure random string that changes once per month for all descriptors and statuses published in that month.
  • The [:3] operator picks the first three bytes from the left of the result and encodes it as two lower-case hexadecimal numbers, a colon, and another four lower-case hexadecimal numbers.
  • Similar to IPv4 addresses (Section 3.5), IPv6 addresses are replaced with syntactical valid addresses in the address range [fd9f:2e19:3bcf::/116] based on a keyed hash function that produces the same sanitized address for a given bridge, IPv6 address, and month.

3.7. Replace TCP ports

SanitizedPort = KeyedHash / 2^2 + 2^15 + 2^14

KeyedHash = SHA256(Port | Fingerprint | Secret)[:2]

  • Port is the 2-byte long binary representation of the TCP port.
  • Fingerprint is the 20-byte long binary representation of the bridge's long-term identity fingerprint.
  • Secret is a 33-byte long secure random string that changes once per month for all descriptors and statuses published in that month.
  • The [:2] operator means that we pick the first two bytes from the left of the result, and the /, ^, and + operators are all integer operators.
  • TCP ports that are 0 in the original are left unchanged.
  • It may be less obvious that TCP ports need to be sanitized, but an unusual TCP port used by a high-value bridge might still stand out and provide yet another way to locate and block the bridge. Therefore, each non-zero TCP port is replaced with a port number in the range from 49152 to 65535, which is reserved for private services, based on a keyed hash function that produces the same sanitized port for a given bridge, TCP port, and month.

3.8. Remove contact information

SanitizedContact = "somebody"

  • If there is contact information in a descriptor, it is replaced by the constant string "somebody". (Note that this sanitizing step is subject to change and maybe be changed in a future version towards retaining the original contact information.)

3.9. Remove extraneous transport information

[Removed.]

  • Bridges may provide transports in addition to the OR protocol and include information about these transports for the bridge distribution service. In that case, any IP addresses, TCP ports, or additional arguments are removed, only leaving in the supported transport names.

3.10. Replace digests in referencing descriptors

SanitizedSha1Digest = SHA1(Sha1Digest)

SanitizedSha256Digest = SHA256(Sha256Digest)

  • Sha1Digest is the 20-byte long binary representation of a descriptor's SHA-1 digest.
  • Sha256Digest is the 32-byte long binary representation of a descriptor's SHA-256 digest.
  • Some descriptors reference other descriptors by their digest. However, these digests are also somewhat sensitive, because it shouldn't be possible to reconstruct the original descriptor with help of these digests. That is why digests in referencing descriptors are replaced with either the hex-encoded SHA-1 hash or the base64-encoded SHA-256 hash of the original digest, depending on which hash algorithm was used to generate the original digest. The resulting digest string in a referencing descriptor can then be matched to an appended digest (Section 3.11) in a referenced descriptor.

3.11. Append digests to referenced descriptors

SanitizedSha1Digest = SHA1(Sha1Digest)

SanitizedSha256Digest = SHA256(Sha256Digest)

  • Sha1Digest is the 20-byte long binary representation of a descriptor's SHA-1 digest.
  • Sha256Digest is the 32-byte long binary representation of a descriptor's SHA-256 digest.
  • As stated above (Section 3.10), some descriptors are referenced by others by their digest. But in contrast to non-sanitized descriptors, it's neither possible to compute the digest of a sanitized descriptor nor is it desirable to include the original digest. The reason is that it shouldn't be possible to reconstruct the original descriptor with help of the original digest. That is why descriptors that are typically referenced from others may contain additional lines with the hex-encoded SHA-1 hash or the base64-encoded SHA-256 hash of the original digest, depending on which hash algorithm would have been used to generate the original digest. The resulting digest string can then be matched to a sanitized digest (Section 3.10) in a referencing descriptor.

4. Server descriptor document format

The document format of sanitized bridge server descriptors resembles the document format of (non-sanitized) server descriptors as much as possible. Also refer to the Tor directory protocol, version 3 specification, as the following sections only specify items that differ from their non-sanitized counterparts.

4.1. Annotations

The bridge authority may prefix descriptors with one or more annotation lines containing metadata, and the sanitizer may add annotation lines with metadata about the sanitizing process.

"@purpose" SP Purpose NL

  • [Removed.]

"@type" SP "bridge-server-descriptor" SP Version

  • [Exactly once.]
  • Version can be one of the following numbers:
    • "1.0" was the first version. There was supposed to be a newer version indicating added "ntor-onion-key" lines, but due to a mistake only the version number of sanitized bridge extra-info descriptors was raised. As a result, there may be sanitized bridge server descriptors with version 1.0 with and without those lines.
    • "1.1" added "master-key-ed25519" and "router-digest-sha256" lines to server descriptors published by bridges using an ed25519 master key.
    • "1.2" introduced sanitized TCP ports.

4.2. Descriptor body

The body of a sanitized bridge server descriptor contains several sanitized items as specified in the following:

"router" SP Nickname SP SanitizedAddress SP SanitizedORPort SP SOCKSPort SP SanitizedDirPort NL

  • [At start, exactly once.]
  • Nickname is the bridge's original, unchanged nickname.
  • SanitizedAddress is the bridge's sanitized IP address (Section 3.5).
  • SanitizedORPort is the bridge's sanitized OR port (Section 3.7) (since version 1.2) or the original OR port (until version 1.1).
  • SOCKSPort is deprecated and always 0, as in the original, non-sanitized server descriptor.
  • SanitizedDirPort is the bridge's sanitized directory port (Section 3.7) (since version 1.2) or the original directory port (until version 1.1).

"or-address" SP SanitizedAddress ":" SanitizedPort NL

  • [Any number.]
  • SanitizedAddress is either an additional sanitized IPv4 address (Section 3.5) or sanitized IPv6 address (Section 3.6).
  • SanitizedPort is an additional sanitized OR port (Section 3.7) (since version 1.2) or original OR port (until version 1.1).

"identity-ed25519" NL CertificateBlock NL

  • [Removed.]

"master-key-ed25519" SP SanitizedMasterKey NL

  • [At most once.]
  • SanitizedMasterKey is the bridge's sanitized ed25519 master key (Section 3.3). (Introduced in version 1.1, not present in earlier versions.)

"fingerprint" SP SanitizedFingerprint NL

  • [At most once.]
  • SanitizedFingerprint is the bridge's sanitized fingerprint (Section 3.2), formatted with a single SP after every 4 characters.

"contact" SP SanitizedContact NL

  • [At most once.]
  • SanitizedContact is the bridge's sanitized contact information (Section 3.8).

"reject" SP ExitPattern NL

  • [Any number.]
  • ExitPattern contains the bridge's sanitized IPv4 address (Section 3.5), if the original line contained the bridge's primary IP address, and is otherwise unchanged. (Note that "accept" lines are exempt from this sanitizing step, which doesn't really make sense and which might change in the future.)

"extra-info-digest" SP SanitizedSha1Digest [SP SanitizedSha256Digest] NL

  • [At most once.]
  • SanitizedSha1Digest is the sanitized SHA-1 digest (Section 3.10) of the corresponding extra-info descriptor.
  • SanitizedSha256Digest is the sanitized SHA-256 digest (Section 3.10) of corresponding extra-info descriptor and is only included if the original line contained a SHA-256 digest.

"family" (SP Name)* NL

  • [At most once.]
  • Name is either the sanitized fingerprint (Section 3.2) or unchanged nickname of another relay or bridge that is purportedly in the same family as this bridge.

"onion-key" NL PublicKeyBlock NL

  • [Removed.]
  • The bridge's medium-term RSA key is removed together with most other public keys, certificates, and signatures (Section 3.4).

"signing-key" NL PublicKeyBlock NL

  • [Removed.]
  • The bridge's long-term RSA key is removed together with most other public keys, certificates, and signatures (Section 3.4).

"onion-key-crosscert" NL SignatureBlock NL

  • [Removed.]
  • This cross signature created with the onion-key is removed together with most other public keys, certificates, and signatures (Section 3.4).

"ntor-onion-key-crosscert" SP PublicKey NL

  • [Removed.]
  • This cross signature created with the ntor-onion-key is removed together with most other public keys, certificates, and signatures (Section 3.4).

"ntor-onion-key" SP NtorOnionKey NL

  • [At most once.]
  • The curve25519 public key used for the ntor circuit extended handshake is included without modification in most sanitized descriptors. This key was originally missing in version 1.0, and there was supposed to be a newer version indicating added "ntor-onion-key" lines. But due to a mistake only the version number of sanitized bridge extra-info descriptors was raised. As a result, there are sanitized bridge server descriptors with version 1.0 with and without this line. All subsequent versions contain this line

"router-sig-ed25519" SP Signature NL

  • [Removed.]
  • The ed25519 signature is removed together with most other public keys, certificates, and signatures (Section 3.4).

"router-signature" NL SignatureBlock NL

  • [Removed.]
  • The RSA signature is removed together with most other public keys, certificates, and signatures (Section 3.4).

"router-digest-sha256" SP SanitizedSha256Digest NL

  • [At most once.]
  • SanitizedSha256Digest is the sanitized SHA-256 digest (Section 3.11) of this descriptor and is only included if the original descriptor contained an ed25519 signature of the descriptor's SHA-256 digest. (Introduced in version 1.1, not present in earlier versions.)

"router-digest" SP SanitizedSha1Digest NL

  • [At end, exactly once.]
  • SanitizedSha1Digest is the sanitized SHA-1 digest (Section 3.11) of this descriptor.

5. Extra-info descriptor document format

The document format of sanitized extra-info descriptors follows the same approach as sanitized server descriptors by changing as few items as possible in their original, non-sanitized counterpart. The original format is specified in the Tor directory protocol, version 3. Only the changes to that specification are listed below.

5.1. Annotations

"@type" SP "bridge-extra-info" SP Version

  • [Exactly once.]
  • Version can be one of the following numbers:
    • "1.0" was the first version.
    • "1.1" added sanitized "transport" lines.
    • "1.2" was supposed to indicate added "ntor-onion-key" lines, but those changes only affected bridge server descriptors, not extra-info descriptors. So, nothing has changed as compared to version 1.1.
    • "1.3" added "master-key-ed25519" and "router-digest-sha256" lines to extra-info descriptors published by bridges using an ed25519 master key.

5.2. Descriptor body

Several items in the extra-info descriptor body are changed or removed as compared to original, non-sanitized descriptors:

"extra-info" SP Nickname SP SanitizedFingerprint NL

  • [At start, exactly once.]
  • Nickname is the bridge's original, unchanged nickname.
  • SanitizedFingerprint is the bridge's sanitized fingerprint (Section 3.2).

"transport" SP TransportName NL

  • [Any number.]
  • TransportName is the transport name as found in the original line.
  • Any further details about this transport (Section 3.9), including any IP addresses, TCP ports, or additional arguments are removed, only leaving in the supported transport names. (Introduced in version 1.1, not present in earlier versions.)

"transport-info SP TransportInfo NL

  • [Removed.]
  • Any lines containing extraneous transport information (Section 3.9) are removed. (Note that these lines are not even specified for original, non-sanitized descriptors.)

"identity-ed25519" NL CertificateBlock NL

  • [Removed.]
  • The RSA signature is removed together with most other public keys, certificates, and signatures (Section 3.4).

"master-key-ed25519" SP SanitizedMasterKey NL

  • [At most once.]
  • SanitizedMasterKey is the bridge's sanitized ed25519 master key (Section 3.3). (Introduced in version 1.3, not present in earlier versions.)

"router-sig-ed25519" SP Signature NL

  • [Removed.]
  • The ed25519 signature is removed together with most other public keys, certificates, and signatures (Section 3.4).

"router-signature" NL SignatureBlock NL

  • [Removed.]
  • The RSA signature is removed together with most other public keys, certificates, and signatures (Section 3.4).

"router-digest-sha256" SP SanitizedSha256Digest NL

  • [At most once.]
  • SanitizedSha256Digest is the sanitized SHA-256 digest (Section 3.11) of this descriptor and is only included if the original descriptor contained an ed25519 signature of the descriptor's SHA-256 digest. (Introduced in version 1.3, not present in earlier versions.)

"router-digest" SP SanitizedSha1Digest NL

  • [At end, exactly once.]
  • SanitizedSha1Digest is the sanitized SHA-1 digest (Section 3.11) of this descriptor.

6. Network status document format

The document format of bridge network statuses is loosely based on the network status format specified in the Tor directory protocol, version 2. However, the preamble of bridge network statuses contains far fewer items than that of (relay) network statuses, and the ones that are similar differ in some of the details. That's why all preamble lines that exist in sanitized bridge network statuses are specified below, not just the ones that differ.

6.1. Annotations

Sanitized bridge network statuses start with one or more annotations:

"@type" SP "bridge-network-status" SP Version NL

  • [Exactly once.]
  • Version can be one of the following numbers:
    • "1.0" was the first version.
    • "1.1" introduced sanitized TCP ports.
    • "1.2" introduced the "fingerprint" line, containing the fingerprint of the bridge authority which produced the document, to the header.

6.2. Preamble

The preamble contains zero or more of the following items in no predefined order:

"published" SP Publication NL

  • [Exactly once.]
  • Publication is the publication time for this document, which is left unchanged in the sanitizing process.

"flag-thresholds" SP Thresholds NL

  • [At most once.]
  • Thresholds are internal performance thresholds that the bridge directory authority had at the moment it was forming a status, which are left unchanged in the sanitizing process. This item was first introduced in Tor directory protocol, version 3.

"fingerprint" SP Fingerprint NL;

  • [At most once.]
  • Fingerprint is the (non-sanitized) SHA-1 hash of the bridge authority's long-term signing key, encoded as 40 upper-case hexadecimal characters, which is either added or left unchanged in the sanitizing process. (Introduced in version 1.2, not present in earlier versions.)

6.3. Router entries

For each bridge, there is one router entry containing one or more items. Similar to the preamble specification, the following specification lists all lines known in sanitized bridge network statuses, including those that are left unchanged in the sanitizing process.

"r" SP Nickname SP SanitizedFingerprint SP SanitizedSha1Digest SP Publication SP SanitizedAddress SP SanitizedORPort SP SanitizedDirPort NL

  • [At start, exactly once.]
  • Nickname is the bridge's original, unchanged nickname.
  • SanitizedFingerprint is the bridge's sanitized fingerprint (Section 3.2).
  • SanitizedSha1Digest is the sanitized SHA-1 digest (Section 3.10) of the corresponding server descriptor.
  • Publication is the publication time for the corresponding server descriptor, which is left unchanged in the sanitizing process.
  • SanitizedAddress is the bridge's sanitized IP address (Section 3.5).
  • SanitizedORPort is the bridge's sanitized OR port (Section 3.7) (since version 1.1) or the original OR port (until version 1.0).
  • SanitizedDirPort is the bridge's sanitized directory port (Section 3.7) (since version 1.1) or the original directory port (until version 1.0).

"a" SP SanitizedAddress ":" SanitizedPort NL

  • [Any number.]
  • SanitizedAddress is either an additional sanitized IPv4 address (Section 3.5) or sanitized IPv6 address (Section 3.6).
  • SanitizedPort is an additional sanitized OR port (Section 3.7).

"s" ... NL

  • [Unchanged.]

"w" ... NL

  • [Unchanged.]

"p" ... NL

  • [Unchanged.]

© 2009–2018 The Tor Project

Contact

This material is supported in part by the National Science Foundation under Grant No. CNS-0959138. Any opinions, finding, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. "Tor" and the "Onion Logo" are registered trademarks of The Tor Project, Inc.. Data on this site is freely available under a CC0 no copyright declaration: To the extent possible under law, the Tor Project has waived all copyright and related or neighboring rights in the data. Graphs are licensed under a Creative Commons Attribution 3.0 United States License.