Documentation
¶
Index ¶
- Variables
- func BootstrapCircuit(auth *DirAuthority, relayInfo *descriptor.RelayInfo, logger *slog.Logger) (*circuit.Circuit, *link.Link, error)
- func DefaultCacheDir() string
- func FetchAuthorityDescriptor(auth *DirAuthority) (*descriptor.RelayInfo, error)
- func FetchConsensus(circ *circuit.Circuit) (string, error)
- func FetchViaBeginDir(circ *circuit.Circuit, urlPath string, maxResponseBytes int) ([]byte, error)
- func ParseMicrodescriptor(text string) (ntorKey [32]byte, ed25519Key [32]byte, hasNtor, hasEd bool)
- func UpdateRelaysWithMicrodescriptors(circ *circuit.Circuit, relays []Relay) error
- func ValidateFreshness(c *Consensus) error
- func ValidateSignatures(text string, certs []KeyCert) error
- type Cache
- func (c *Cache) LoadConsensus() (string, bool)
- func (c *Cache) LoadKeyCerts() ([]KeyCert, error)
- func (c *Cache) LoadMicrodescriptors(relays []Relay) int
- func (c *Cache) NeedsRefresh() bool
- func (c *Cache) SaveConsensus(text string, freshUntil, validUntil time.Time) error
- func (c *Cache) SaveKeyCerts(certs []KeyCert) error
- func (c *Cache) SaveMicrodescriptors(relays []Relay) error
- type Consensus
- type DirAuthority
- type KeyCert
- type Relay
- type RelayFlags
Constants ¶
This section is empty.
Variables ¶
var DirAuthorities = []DirAuthority{
newDirAuthority("moria1", "128.31.0.39", 9201, 9231, "F533C81CEF0BC0267857C99B2F471ADF249FA232"),
newDirAuthority("tor26", "217.196.147.77", 443, 80, "2F3DF9CA0E5D36F2685A2DA67184EB8DCB8CBA8C"),
newDirAuthority("dizum", "45.66.35.11", 443, 80, "E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58"),
newDirAuthority("gabelmoo", "131.188.40.189", 443, 80, "ED03BB616EB2F60BEC80151114BB25CEF515B226"),
newDirAuthority("dannenberg", "193.23.244.244", 443, 80, "0232AF901C31A04EE9848595AF9BB7620D4C5B2E"),
newDirAuthority("maatuska", "171.25.193.9", 80, 443, "49015F787433103580E3B66A1707A00E60F2D15B"),
newDirAuthority("longclaw", "199.58.81.140", 443, 80, "23D15D965BC35114467363C165C4F724B64B4F66"),
newDirAuthority("bastet", "204.13.164.118", 443, 80, "27102BC123E7AF1D4741AE047E160C91ADC76B21"),
newDirAuthority("faravahar", "216.218.219.41", 443, 80, "70849B868D606BAECFB6128C5E3D782029AA394F"),
}
DirAuthorities lists the 9 Tor directory authorities (from C Tor auth_dirs.inc, 2026-03). Serge is intentionally excluded: it is a bridge authority (no v3ident), not a directory authority.
Functions ¶
func BootstrapCircuit ¶ added in v0.1.6
func BootstrapCircuit(auth *DirAuthority, relayInfo *descriptor.RelayInfo, logger *slog.Logger) (*circuit.Circuit, *link.Link, error)
BootstrapCircuit builds a 1-hop circuit to a directory authority for bootstrapping (fetching consensus, key certificates, microdescriptors). The caller must close both the circuit and the link when done.
relayInfo contains the authority's relay identity (NodeID) and ntor-onion-key, typically obtained via FetchAuthorityDescriptor over plaintext HTTP. Note: the relay's NodeID (from its server descriptor) differs from the authority's V3Ident (voting key) — the ntor handshake requires the relay NodeID.
The circuit's read loop is started before returning because bootstrap circuits are used immediately for FetchViaBeginDir, which requires the read loop to dispatch relay cells to streams.
func DefaultCacheDir ¶
func DefaultCacheDir() string
DefaultCacheDir returns the default cache directory (~/.daphne/tor-cache/).
func FetchAuthorityDescriptor ¶ added in v0.1.6
func FetchAuthorityDescriptor(auth *DirAuthority) (*descriptor.RelayInfo, error)
FetchAuthorityDescriptor fetches the server descriptor for a directory authority via plaintext HTTP and returns the parsed RelayInfo (including NodeID and ntor-onion-key). The descriptor is fully parsed and RSA-signature-verified using descriptor.ParseDescriptor for defense-in-depth.
Trust model: the descriptor is fetched over plaintext HTTP, so a MITM could serve a valid-but-wrong descriptor signed by a different relay's RSA key. A fingerprint cross-check is not possible here because V3Ident (the authority's voting key fingerprint) differs from the relay identity fingerprint in the server descriptor — authorities have two distinct RSA keys. However, the subsequent BootstrapCircuit performs an ntor handshake using the relay identity from this descriptor, and the TLS CERTS handshake validates the full certificate chain. A MITM would therefore need to control a relay with a valid RSA signing key AND complete the ntor handshake, which requires possession of the corresponding private key.
func FetchConsensus ¶
FetchConsensus fetches the microdescriptor consensus via a BEGIN_DIR stream over the given circuit. The circuit's last hop must support directory requests (e.g., a directory authority).
func FetchViaBeginDir ¶ added in v0.1.6
FetchViaBeginDir fetches a resource from a Tor relay's directory port using a BEGIN_DIR stream over the given circuit. The circuit's last hop must support directory requests (e.g., an HSDir relay or a directory authority).
urlPath is the HTTP path to request (e.g., "/tor/status-vote/current/consensus-microdesc"). maxResponseBytes limits the response body size.
func ParseMicrodescriptor ¶
ParseMicrodescriptor extracts ntor-onion-key and Ed25519 identity from a microdescriptor.
func UpdateRelaysWithMicrodescriptors ¶
UpdateRelaysWithMicrodescriptors fetches microdescriptors for the given relays via a BEGIN_DIR stream on the provided circuit and updates their ntor keys and Ed25519 identities.
func ValidateFreshness ¶
ValidateFreshness checks that the consensus is currently valid.
func ValidateSignatures ¶
ValidateSignatures cryptographically verifies RSA signatures on the consensus. It requires at least 5 valid signatures from known directory authorities. Returns an error if certs is nil or empty.
Types ¶
type Cache ¶
type Cache struct {
Dir string
}
Cache handles caching of consensus and microdescriptor data to disk.
func (*Cache) LoadConsensus ¶
LoadConsensus attempts to load a cached consensus. Returns the consensus text and true if the cache is valid (valid-until has not passed), or empty string and false if no valid cache exists.
func (*Cache) LoadKeyCerts ¶
LoadKeyCerts loads cached authority key certificates.
func (*Cache) LoadMicrodescriptors ¶
LoadMicrodescriptors loads cached microdescriptor data and applies it to the given relay slice. Returns the number of relays updated.
func (*Cache) NeedsRefresh ¶
NeedsRefresh returns true if the cached consensus is past its fresh-until time.
func (*Cache) SaveConsensus ¶
SaveConsensus saves a consensus to the cache directory.
func (*Cache) SaveKeyCerts ¶
SaveKeyCerts saves authority key certificates to cache.
func (*Cache) SaveMicrodescriptors ¶
SaveMicrodescriptors saves microdescriptor data from the given relays to cache.
type Consensus ¶
type Consensus struct {
ValidAfter time.Time
FreshUntil time.Time
ValidUntil time.Time
Relays []Relay
BandwidthWeights map[string]int64 // Wgg, Wgm, Wmg, Wmm, etc.
}
Consensus represents a parsed Tor microdescriptor consensus.
func ParseConsensus ¶
ParseConsensus parses a microdescriptor consensus document.
type DirAuthority ¶ added in v0.1.6
type DirAuthority struct {
Nickname string
Address string
ORPort uint16
DirPort uint16
V3Ident string // SHA-1 of RSA identity key, uppercase hex
Fingerprint [20]byte // SHA-1 of RSA identity key, binary
Ed25519ID [32]byte // Ed25519 identity key; zero until populated from live consensus/descriptor
}
DirAuthority represents a Tor directory authority with its identity and network info.
func (*DirAuthority) DirAddr ¶ added in v0.1.6
func (a *DirAuthority) DirAddr() string
DirAddr returns "address:dirport" for the given authority.
type KeyCert ¶
type KeyCert struct {
IdentityFingerprint string // SHA-1 of identity key DER, uppercase hex
SigningKeyDigest string // SHA-1 of signing key DER, uppercase hex
SigningKey *rsa.PublicKey // The medium-term signing key
Expires time.Time // dir-key-expires
}
KeyCert represents a parsed directory authority key certificate.
func FetchKeyCerts ¶
FetchKeyCerts fetches authority key certificates via a BEGIN_DIR circuit.
func ParseKeyCerts ¶
ParseKeyCerts parses concatenated authority key certificate text. Only returns certificates for known authorities that have not expired.
type Relay ¶
type Relay struct {
Nickname string
Identity [20]byte // SHA-1 of RSA identity key (base64-decoded from "r" line)
Address string // IPv4 address
ORPort uint16
DirPort uint16
Flags RelayFlags
Bandwidth int64 // From "w Bandwidth=" line
MicrodescDigest string // Base64 microdesc digest from "m" line
// Populated after microdescriptor fetch
NtorOnionKey [32]byte
Ed25519ID [32]byte
HasNtorKey bool
HasEd25519 bool
}
Relay represents a router entry in the consensus.