pearl

package module
v0.0.0-...-15325b8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 1, 2020 License: MIT Imports: 37 Imported by: 0

README

pearl

Tor relay implementation in Golang.

Note this is a work in progress. Implements minimal subset of the Tor protocol to act as a relay (non exit node).

go.dev Reference Build status Coverage Go Report Card

Documentation

Overview

Package pearl implements parts of the Tor protocol.

Index

Constants

TAP handshake data sizes.

Reference: https://github.com/torproject/torspec/blob/f9eeae509344dcfd1f185d0130a0055b00131cea/tor-spec.txt#L1024-L1025

Define TAP_C_HANDSHAKE_LEN as DH_LEN+KEY_LEN+PK_PAD_LEN.
Define TAP_S_HANDSHAKE_LEN as DH_LEN+HASH_LEN.
View Source
const (
	HandshakeTagNTOR = "ntorNTORntorNTOR"
)

Recognized HTAG values.

Reference: https://github.com/torproject/torspec/blob/f9eeae509344dcfd1f185d0130a0055b00131cea/tor-spec.txt#L892-L894

migration. See 5.1.2.1 below. Recognized HTAG values are:

    ntor -- 'ntorNTORntorNTOR'
View Source
const MaxPayloadLength = 509

MaxPayloadLength is the longest allowable cell payload.

Reference: https://github.com/torproject/torspec/blob/4074b891e53e8df951fc596ac6758d74da290c60/tor-spec.txt#L65

PAYLOAD_LEN -- The longest allowable cell payload, in bytes. (509)

Variables

View Source
var (
	ErrUnexpectedCommand = errors.New("unexpected command")
	ErrShortCellPayload  = errors.New("cell payload too short")
)

Common error types.

View Source
var (
	ErrUnencodableAddress = errors.New("could not encode address")
	ErrParseIPFromAddress = errors.New("could not parse ip from address")
)

Errors which can occur when parsing NETINFO cells.

View Source
var ErrNoCommonVersion = errors.New("no common version found")

ErrNoCommonVersion is returned from ResolveVersion when the two lists of supported versions do not have any versions in common.

View Source
var ErrUnknownCommand = errors.New("unknown command")

ErrUnknownCommand is returned when a cell is seen with an unknown command.

View Source
var ErrVersionsCellOddLength = errors.New("versions cell with odd length")

ErrVersionsCellOddLength is returned when we receive a versions cell of odd length. This should never happen, because the body should be a list of 16-bit integers.

View Source
var SupportedLinkProtocolVersions = []LinkProtocolVersion{4}

SupportedLinkProtocolVersions contains the list of link protocol versions supported by this relay.

Functions

func BuildAndSend

func BuildAndSend(s CellSender, b CellBuilder) error

func CellLogger

func CellLogger(l log.Logger, cell Cell) log.Logger

func Create2Handler

func Create2Handler(conn *Connection, c Cell) error

Create2Handler handles a received CREATE2 cell.

func CreateFastHandler

func CreateFastHandler(conn *Connection, c Cell) error

CreateFastHandler handles a received CREATE_FAST cell.

func CreateHandler

func CreateHandler(conn *Connection, c Cell) error

CreateHandler handles a received CREATE cell.

func DecodeAddress

func DecodeAddress(b []byte) (net.IP, []byte, error)

DecodeAddress decodes the given bytes into an IP and returns the remaining.

func EncodeAddress

func EncodeAddress(ip net.IP) []byte

EncodeAddress encodes the given IP address into the byte format appropriate for NETINFO cells and other purposes.

func IsCertType

func IsCertType(c byte) bool

IsCertType determines whether c is a possible CertType value.

func IsCircuitErrorCode

func IsCircuitErrorCode(c byte) bool

IsCircuitErrorCode determines whether c is a possible CircuitErrorCode value.

func IsCommand

func IsCommand(c byte) bool

IsCommand determines whether c is a possible Command value.

func IsLinkSpecType

func IsLinkSpecType(l byte) bool

IsLinkSpecType determines whether l is a possible LinkSpecType value.

func IsRelayCommand

func IsRelayCommand(r byte) bool

IsRelayCommand determines whether r is a possible RelayCommand value.

func IsStreamCloseReason

func IsStreamCloseReason(s byte) bool

IsStreamCloseReason determines whether s is a possible StreamCloseReason value.

func LaunchCircuit

func LaunchCircuit(conn *Connection, id CircID, k *CircuitKeys) error

func ProcessHandshake

func ProcessHandshake(conn *Connection, req CreateRequest) error

ProcessHandshake directs the creation request to the correct handshake mechanism.

func ProcessHandshakeNTOR

func ProcessHandshakeNTOR(conn *Connection, c CreateRequest) error

func ProcessHandshakeTAP

func ProcessHandshakeTAP(conn *Connection, c CreateRequest) error

ProcessHandshakeTAP handles the "TAP" handshake.

func RelayCellLogger

func RelayCellLogger(l log.Logger, r RelayCell) log.Logger

Types

type AuthChallengeCell

type AuthChallengeCell struct {
	Challenge [32]byte
	Methods   []AuthMethod
}

AuthChallengeCell represents an AUTH_CHALLENGE cell.

func NewAuthChallengeCell

func NewAuthChallengeCell(methods []AuthMethod) (*AuthChallengeCell, error)

NewAuthChallengeCell builds an AUTH_CHALLENGE cell with the given method IDs. The challenge is generated at random.

func NewAuthChallengeCellStandard

func NewAuthChallengeCellStandard() (*AuthChallengeCell, error)

NewAuthChallengeCellStandard builds an AUTH_CHALLENGE cell for method 1.

func ParseAuthChallengeCell

func ParseAuthChallengeCell(c Cell) (*AuthChallengeCell, error)

ParseAuthChallengeCell parses c as an AUTH_CHALLENGE cell.

func (AuthChallengeCell) Cell

func (a AuthChallengeCell) Cell() (Cell, error)

Cell constructs the cell bytes.

func (AuthChallengeCell) SupportsMethod

func (a AuthChallengeCell) SupportsMethod(m AuthMethod) bool

type AuthMethod

type AuthMethod uint16

AuthMethod represents an authentication method ID.

var (
	AuthMethodRSASHA256TLSSecret   AuthMethod = 1
	AuthMethodEd25519SHA256RFC5705 AuthMethod = 3
)

Defined AuthMethod values.

func (AuthMethod) String

func (m AuthMethod) String() string

String represents the AuthMethod as a string. This is also the TYPE value expected in AUTHENTICATE cells.

type AuthRSASHA256TLSSecret

type AuthRSASHA256TLSSecret struct {
	AuthKey           *rsa.PrivateKey
	ClientIdentityKey *rsa.PublicKey
	ServerIdentityKey *rsa.PublicKey
	ServerLogHash     []byte
	ClientLogHash     []byte
	ServerLinkCert    []byte
	TLSMasterSecret   []byte
	TLSClientRandom   []byte
	TLSServerRandom   []byte
}

func (AuthRSASHA256TLSSecret) Body

func (a AuthRSASHA256TLSSecret) Body() ([]byte, error)

func (AuthRSASHA256TLSSecret) CID

func (a AuthRSASHA256TLSSecret) CID() ([]byte, error)

func (AuthRSASHA256TLSSecret) Cell

func (a AuthRSASHA256TLSSecret) Cell() (Cell, error)

func (AuthRSASHA256TLSSecret) GoString

func (a AuthRSASHA256TLSSecret) GoString() string

func (AuthRSASHA256TLSSecret) SCERT

func (a AuthRSASHA256TLSSecret) SCERT() [32]byte

func (AuthRSASHA256TLSSecret) SID

func (a AuthRSASHA256TLSSecret) SID() ([]byte, error)

func (AuthRSASHA256TLSSecret) SignedBody

func (a AuthRSASHA256TLSSecret) SignedBody() ([]byte, error)

func (AuthRSASHA256TLSSecret) TLSSecrets

func (a AuthRSASHA256TLSSecret) TLSSecrets() []byte

type AuthRSASHA256TLSSecretPayload

type AuthRSASHA256TLSSecretPayload []byte

func NewAuthRSASHA256TLSSecretPayload

func NewAuthRSASHA256TLSSecretPayload(b []byte) (AuthRSASHA256TLSSecretPayload, error)

func (AuthRSASHA256TLSSecretPayload) Body

func (AuthRSASHA256TLSSecretPayload) Random

func (p AuthRSASHA256TLSSecretPayload) Random() []byte

func (AuthRSASHA256TLSSecretPayload) Signature

func (p AuthRSASHA256TLSSecretPayload) Signature() []byte

func (AuthRSASHA256TLSSecretPayload) ToBeSigned

func (p AuthRSASHA256TLSSecretPayload) ToBeSigned() []byte

type AuthenticateCell

type AuthenticateCell struct {
	Method         AuthMethod
	Authentication []byte
}

AuthenticateCell represents an AUTHENTICATE cell.

func ParseAuthenticateCell

func ParseAuthenticateCell(c Cell) (*AuthenticateCell, error)

ParseAuthenticateCell parses Cell c as an AUTHENTICATE cell.

func (AuthenticateCell) Cell

func (a AuthenticateCell) Cell() (Cell, error)

Cell builds a cell from the AuthenticateCell payload.

type Cell

type Cell interface {
	CircID() CircID
	Command() Command
	Payloaded
	Bytes() []byte
}

Cell represents a cell.

func NewCellEmptyPayload

func NewCellEmptyPayload(circID CircID, cmd Command, n uint16) Cell

NewCellEmptyPayload builds a variable-length Cell with an empty payload of size n bytes.

func NewCellFromBuffer

func NewCellFromBuffer(x []byte) Cell

NewCellFromBuffer builds a Cell from the given bytes.

func NewFixedCell

func NewFixedCell(circID CircID, cmd Command) Cell

NewFixedCell builds a fixed-size cell.

func NewLegacyCell

func NewLegacyCell(c Cell) Cell

type CellBuilder

type CellBuilder interface {
	Cell() (Cell, error)
}

CellBuilder can build a cell. REVIEW(mbm): CellMarshaler?

type CellChan

type CellChan struct {
	C chan Cell
	// contains filtered or unexported fields
}

func NewCellChan

func NewCellChan(c chan Cell, done chan struct{}) *CellChan

func (*CellChan) ReceiveCell

func (ch *CellChan) ReceiveCell() (Cell, error)

func (*CellChan) SendCell

func (ch *CellChan) SendCell(cell Cell) error

type CellReceiver

type CellReceiver interface {
	ReceiveCell() (Cell, error)
}

CellReceiver can receive Cells.

type CellReceiverSender

type CellReceiverSender interface {
	CellSender
	CellReceiver
}

type CellSender

type CellSender interface {
	SendCell(Cell) error
}

CellSender can send a Cell.

func NewCellWriter

func NewCellWriter(w io.Writer, l log.Logger) CellSender

type CellSenderCloser

type CellSenderCloser interface {
	CellSender
	io.Closer
}

type CellUnmarshaler

type CellUnmarshaler interface {
	UnmarshalCell(Cell) error
}

type CertCellEntry

type CertCellEntry struct {
	Type    CertType
	CertDER []byte
}

CertCellEntry represents one certificate in a CERTS cell.

type CertType

type CertType byte

CertType is a certificate type code for CERTS cells.

const (
	CertTypeLink            CertType = 1
	CertTypeIdentity        CertType = 2
	CertTypeAuth            CertType = 3
	CertTypeEd25519Signing  CertType = 4
	CertTypeEd25519Link     CertType = 5
	CertTypeEd25519Auth     CertType = 6
	CertTypeEd25519Identity CertType = 7
)

All possible CertType values.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L594-L601

Relevant certType values are:
   1: Link key certificate certified by RSA1024 identity
   2: RSA1024 Identity certificate, self-signed.
   3: RSA1024 AUTHENTICATE cell link certificate, signed with RSA1024 key.
   4: Ed25519 signing key, signed with identity key.
   5: TLS link certificate, signed with ed25519 signing key.
   6: Ed25519 AUTHENTICATE cell key, signed with ed25519 signing key.
   7: Ed25519 identity, signed with RSA identity.

func (CertType) String

func (c CertType) String() string

type CertsCell

type CertsCell struct {
	Certs []CertCellEntry
}

CertsCell is a CERTS cell.

func ParseCertsCell

func ParseCertsCell(c Cell) (*CertsCell, error)

func (*CertsCell) AddCert

func (c *CertsCell) AddCert(t CertType, crt *x509.Certificate)

AddCert adds a certificate to the cell.

func (*CertsCell) AddCertDER

func (c *CertsCell) AddCertDER(t CertType, der []byte)

AddCertDER adds a DER-encoded certificate to the cell.

func (CertsCell) Cell

func (c CertsCell) Cell() (Cell, error)

Cell builds the cell.

func (*CertsCell) CountType

func (c *CertsCell) CountType(t CertType) int

CountType returns the number of certificates in the cell of the given type.

func (*CertsCell) Lookup

func (c *CertsCell) Lookup(t CertType) ([]byte, error)

Lookup is like Search except it will error if there is no such certificate.

func (*CertsCell) LookupPublicKey

func (c *CertsCell) LookupPublicKey(t CertType) (*rsa.PublicKey, error)

LookupPublicKey is like Lookup but it returns only the public key.

func (*CertsCell) LookupX509

func (c *CertsCell) LookupX509(t CertType) (*x509.Certificate, error)

LookupX509 is like Lookup except it also parses the certificate as X509.

func (*CertsCell) Search

func (c *CertsCell) Search(t CertType) ([]byte, error)

Search looks for a certificate of type t in the cell. If found it returns the DER-encoded certificate. Errors if there are multiple certificates of that type. Returns nil if there is no such certificate.

func (*CertsCell) ValidateInitiatorRSAOnly

func (c *CertsCell) ValidateInitiatorRSAOnly() error

func (*CertsCell) ValidateResponderRSAOnly

func (c *CertsCell) ValidateResponderRSAOnly(peerCerts []*x509.Certificate) error

ValidateResponderRSAOnly checks whether the certificate cell matches requirements for a responder. Requires the TLS peer certiciates for comparison.

type CircID

type CircID uint32

CircID is a circuit ID.

func GenerateCircID

func GenerateCircID(msb uint32) CircID

GenerateCircID generates a 4-byte circuit ID with the given most significant bit.

type CircuitCryptoState

type CircuitCryptoState struct {
	// contains filtered or unexported fields
}

func NewCircuitCryptoState

func NewCircuitCryptoState(d, k []byte) *CircuitCryptoState

func (*CircuitCryptoState) Decrypt

func (c *CircuitCryptoState) Decrypt(b []byte)

func (*CircuitCryptoState) Digest

func (c *CircuitCryptoState) Digest() uint32

func (*CircuitCryptoState) Encrypt

func (c *CircuitCryptoState) Encrypt(b []byte)

func (*CircuitCryptoState) EncryptOrigin

func (c *CircuitCryptoState) EncryptOrigin(b []byte)

func (*CircuitCryptoState) RewindDigest

func (c *CircuitCryptoState) RewindDigest()

func (*CircuitCryptoState) Sum

func (c *CircuitCryptoState) Sum() []byte

type CircuitErrorCode

type CircuitErrorCode byte

CircuitErrorCode is an error code classifying a problem with a circuit.

const (
	CircuitErrorNone          CircuitErrorCode = 0
	CircuitErrorProtocol      CircuitErrorCode = 1
	CircuitErrorInternal      CircuitErrorCode = 2
	CircuitErrorRequested     CircuitErrorCode = 3
	CircuitErrorHibernating   CircuitErrorCode = 4
	CircuitErrorResourcelimit CircuitErrorCode = 5
	CircuitErrorConnectfailed CircuitErrorCode = 6
	CircuitErrorOrIdentity    CircuitErrorCode = 7
	CircuitErrorOrConnClosed  CircuitErrorCode = 8
	CircuitErrorFinished      CircuitErrorCode = 9
	CircuitErrorTimeout       CircuitErrorCode = 10
	CircuitErrorDestroyed     CircuitErrorCode = 11
	CircuitErrorNosuchservice CircuitErrorCode = 12
)

All possible CircuitErrorCode values.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L1337-L1352

The error codes are:
  0 -- NONE            (No reason given.)
  1 -- PROTOCOL        (Tor protocol violation.)
  2 -- INTERNAL        (Internal error.)
  3 -- REQUESTED       (A client sent a TRUNCATE command.)
  4 -- HIBERNATING     (Not currently operating; trying to save bandwidth.)
  5 -- RESOURCELIMIT   (Out of memory, sockets, or circuit IDs.)
  6 -- CONNECTFAILED   (Unable to reach relay.)
  7 -- OR_IDENTITY     (Connected to relay, but its OR identity was not
                        as expected.)
  8 -- OR_CONN_CLOSED  (The OR connection that was carrying this circuit
                        died.)
  9 -- FINISHED        (The circuit has expired for being dirty or old.)
 10 -- TIMEOUT         (Circuit construction took too long)
 11 -- DESTROYED       (The circuit was destroyed w/o client TRUNCATE)
 12 -- NOSUCHSERVICE   (Request for unknown hidden service)

func (CircuitErrorCode) String

func (c CircuitErrorCode) String() string

type CircuitKeys

type CircuitKeys struct {
	KH []byte // Derivative key data
	Df []byte // Forward digest
	Db []byte // Backward digest
	Kf []byte // Forward key
	Kb []byte // Backward key
}

func BuildCircuitKeysKDFTOR

func BuildCircuitKeysKDFTOR(s []byte) (*CircuitKeys, error)

BuildCircuitKeysKDFTOR builds circuit keys via the KDF-TOR method from a shared secret s.

func BuildCircuitKeysNTOR

func BuildCircuitKeysNTOR(r io.Reader) (*CircuitKeys, error)

BuildCircuitKeysNTOR generates Circuit key material from r.

func (*CircuitKeys) BackwardCryptoState

func (k *CircuitKeys) BackwardCryptoState() *CircuitCryptoState

func (*CircuitKeys) ForwardCryptoState

func (k *CircuitKeys) ForwardCryptoState() *CircuitCryptoState
type CircuitLink interface {
	CircID() CircID
	CellReceiverSender
	Destroy(CircuitErrorCode) error
}
func NewCircuitLink(conn *Connection, id CircID, r CellReceiver) CircuitLink

type ClientHandshakeDataNTOR

type ClientHandshakeDataNTOR []byte

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L1075-L1077

H_LENGTH  = 32.
ID_LENGTH = 20.
G_LENGTH  = 32

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L1095-L1098

and generates a client-side handshake with contents:
    NODEID      Server identity digest  [ID_LENGTH bytes]
    KEYID       KEYID(B)                [H_LENGTH bytes]
    CLIENT_PK   X                       [G_LENGTH bytes]

func (ClientHandshakeDataNTOR) ClientPK

func (h ClientHandshakeDataNTOR) ClientPK() [32]byte

func (ClientHandshakeDataNTOR) KeyID

func (h ClientHandshakeDataNTOR) KeyID() []byte

func (ClientHandshakeDataNTOR) ServerFingerprint

func (h ClientHandshakeDataNTOR) ServerFingerprint() []byte

type Command

type Command byte

Command represents a cell packet command byte.

const (
	CommandPadding          Command = 0
	CommandCreate           Command = 1
	CommandCreated          Command = 2
	CommandRelay            Command = 3
	CommandDestroy          Command = 4
	CommandCreateFast       Command = 5
	CommandCreatedFast      Command = 6
	CommandVersions         Command = 7
	CommandNetinfo          Command = 8
	CommandRelayEarly       Command = 9
	CommandCreate2          Command = 10
	CommandCreated2         Command = 11
	CommandPaddingNegotiate Command = 12
	CommandAuthChallenge    Command = 130
	CommandAuthenticate     Command = 131
	CommandAuthorize        Command = 132
	CommandCerts            Command = 129
	CommandVpadding         Command = 128
)

All possible Command values.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L446-L467

The 'Command' field of a fixed-length cell holds one of the following
values:
      0 -- PADDING     (Padding)                 (See Sec 7.2)
      1 -- CREATE      (Create a circuit)        (See Sec 5.1)
      2 -- CREATED     (Acknowledge create)      (See Sec 5.1)
      3 -- RELAY       (End-to-end data)         (See Sec 5.5 and 6)
      4 -- DESTROY     (Stop using a circuit)    (See Sec 5.4)
      5 -- CREATE_FAST (Create a circuit, no PK) (See Sec 5.1)
      6 -- CREATED_FAST (Circuit created, no PK) (See Sec 5.1)
      8 -- NETINFO     (Time and address info)   (See Sec 4.5)
      9 -- RELAY_EARLY (End-to-end data; limited)(See Sec 5.6)
      10 -- CREATE2    (Extended CREATE cell)    (See Sec 5.1)
      11 -- CREATED2   (Extended CREATED cell)    (See Sec 5.1)
      12 -- PADDING_NEGOTIATE   (Padding negotiation)    (See Sec 7.2)

 Variable-length command values are:
      7 -- VERSIONS    (Negotiate proto version) (See Sec 4)
      128 -- VPADDING  (Variable-length padding) (See Sec 7.2)
      129 -- CERTS     (Certificates)            (See Sec 4.2)
      130 -- AUTH_CHALLENGE (Challenge value)    (See Sec 4.3)
      131 -- AUTHENTICATE (Client authentication)(See Sec 4.5)
      132 -- AUTHORIZE (Client authorization)    (Not yet used)

func (Command) IsVariableLength

func (c Command) IsVariableLength() bool

IsCommandVariableLength determines whether a cell for the given command code is variable length.

func (Command) PayloadOffset

func (c Command) PayloadOffset() int

PayloadOffset computes the payload offset from the start of cell data for the given command.

func (Command) String

func (c Command) String() string

type ConnID

type ConnID uint64

func NewConnID

func NewConnID() ConnID

type Connection

type Connection struct {
	CellReceiver
	CellSender
	// contains filtered or unexported fields
}

Connection encapsulates a router connection.

func NewClient

func NewClient(r *Router, conn net.Conn, logger log.Logger) (*Connection, error)

NewClient constructs a client-side connection.

func NewServer

func NewServer(r *Router, conn net.Conn, logger log.Logger) (*Connection, error)

NewServer constructs a server connection.

func (*Connection) ConnID

func (c *Connection) ConnID() ConnID

func (*Connection) Fingerprint

func (c *Connection) Fingerprint() (Fingerprint, error)

Fingerprint returns the fingerprint of the connected peer.

func (*Connection) PeerAuthenticated

func (c *Connection) PeerAuthenticated() bool

func (*Connection) Serve

func (c *Connection) Serve() error

func (*Connection) StartClient

func (c *Connection) StartClient() error

type ConnectionHint

type ConnectionHint interface {
	Fingerprinted
	Addresses() ([]net.Addr, error)
}

ConnectionHint specifies how to connect to a relay.

TODO(mbm): bad name? perhaps Addr? TODO(mbm): should not return errors?

type ConnectionManager

type ConnectionManager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ConnectionManager manages a collection of Connections.

func NewConnectionManager

func NewConnectionManager() *ConnectionManager

func (*ConnectionManager) AddConnection

func (m *ConnectionManager) AddConnection(c *Connection) error

func (*ConnectionManager) Connection

func (m *ConnectionManager) Connection(fp Fingerprint) (*Connection, bool)

func (*ConnectionManager) RemoveConnection

func (m *ConnectionManager) RemoveConnection(c *Connection) error

type Create2Cell

type Create2Cell struct {
	CircID        CircID
	HandshakeType HandshakeType
	HandshakeData []byte
}

Create2Cell represents a CREATE2 cell.

func ParseCreate2Cell

func ParseCreate2Cell(c Cell) (*Create2Cell, error)

ParseCreate2Cell parses a CREATE2 cell.

func (Create2Cell) Cell

func (c Create2Cell) Cell() (Cell, error)

Cell builds a cell from the CREATE2 payload.

type CreateRequest

type CreateRequest struct {
	CircID        CircID
	CreateType    Command
	HandshakeType HandshakeType
	HandshakeData []byte
}

REVIEW(mbm): CreateRequest as an interface?

type Created2Cell

type Created2Cell struct {
	CircID        CircID
	HandshakeData []byte
}

Created2Cell represents a CREATED2 cell.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L873-L875

A CREATED2 cell contains:
    HLEN      (Server Handshake Data Len) [2 bytes]
    HDATA     (Server Handshake Data)     [HLEN bytes]

func (Created2Cell) Cell

func (c Created2Cell) Cell() (Cell, error)

Cell builds a cell from the CREATED2 payload.

func (Created2Cell) Payload

func (c Created2Cell) Payload() []byte

Payload returns just the payload part of the CREATED2 cell.

func (*Created2Cell) UnmarshalCell

func (cell *Created2Cell) UnmarshalCell(c Cell) error

type CreatedCell

type CreatedCell struct {
	CircID        CircID
	HandshakeData []byte
}

CreatedCell represents a CREATED cell.

Reference: https://github.com/torproject/torspec/blob/0fd44031bfd6c6c822bfb194e54a05118c9625e2/tor-spec.txt#L896-L897

The format of a CREATED cell is:
    HDATA     (Server Handshake Data)     [TAP_S_HANDSHAKE_LEN bytes]

func (*CreatedCell) Payload

func (cell *CreatedCell) Payload() []byte

func (*CreatedCell) UnmarshalCell

func (cell *CreatedCell) UnmarshalCell(c Cell) error

type DestroyCell

type DestroyCell struct {
	CircID CircID
	Reason CircuitErrorCode
}

func NewDestroyCell

func NewDestroyCell(id CircID, reason CircuitErrorCode) *DestroyCell

func ParseDestroyCell

func ParseDestroyCell(c Cell) (*DestroyCell, error)

func (DestroyCell) Cell

func (d DestroyCell) Cell() Cell

type Extend2Payload

type Extend2Payload struct {
	LinkSpecs     []LinkSpec
	HandshakeData []byte
}

func (*Extend2Payload) Addresses

func (e *Extend2Payload) Addresses() ([]net.Addr, error)

func (*Extend2Payload) Fingerprint

func (e *Extend2Payload) Fingerprint() (Fingerprint, error)

func (*Extend2Payload) Handshake

func (e *Extend2Payload) Handshake() []byte

func (*Extend2Payload) UnmarshalBinary

func (e *Extend2Payload) UnmarshalBinary(p []byte) error

type ExtendPayload

type ExtendPayload struct {
	IP        net.IP
	Port      uint16
	OnionSkin []byte
	Identity  []byte
}

func (*ExtendPayload) Addresses

func (e *ExtendPayload) Addresses() ([]net.Addr, error)

func (*ExtendPayload) Fingerprint

func (e *ExtendPayload) Fingerprint() (Fingerprint, error)

func (*ExtendPayload) Handshake

func (e *ExtendPayload) Handshake() []byte

func (*ExtendPayload) UnmarshalBinary

func (e *ExtendPayload) UnmarshalBinary(p []byte) error

type Fingerprint

type Fingerprint [20]byte

Fingerprint is a relay identity digest (legacy SHA-1).

func NewFingerprintFromBytes

func NewFingerprintFromBytes(b []byte) (Fingerprint, error)

type Fingerprinted

type Fingerprinted interface {
	Fingerprint() (Fingerprint, error)
}

Fingerprinted is something with a fingerprint.

type Handshake

type Handshake struct {
	Conn        *tls.Conn
	Link        HandshakeLink
	TLSContext  *TLSContext
	IdentityKey *rsa.PublicKey

	PeerFingerprint []byte
	// contains filtered or unexported fields
}

func (*Handshake) Client

func (c *Handshake) Client() error

func (*Handshake) Server

func (c *Handshake) Server() error
type HandshakeLink interface {
	CellSender
	LegacyCellReceiver
	InboundDigest() []byte
	OutboundDigest() []byte
}

HashedLink keeps a running hash of traffic in either direction. Intended to support the handshake process.

func NewHandshakeLink(r io.Reader, w io.Writer, l log.Logger) HandshakeLink

type HandshakeType

type HandshakeType uint16

HandshakeType is an identifier for a circuit handshake type.

const (
	HandshakeTypeTAP  HandshakeType = 0
	HandshakeTypeNTOR HandshakeType = 2
)

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L877-L880

Recognized handshake types are:
    0x0000  TAP  -- the original Tor handshake; see 5.1.3
    0x0001  reserved
    0x0002  ntor -- the ntor+curve25519+sha256 handshake; see 5.1.4

type LegacyCellReceiver

type LegacyCellReceiver interface {
	CellReceiver
	ReceiveLegacyCell() (Cell, error)
}

CellReceiver can receive legacy Cells (circ ID length 2).

func NewCellReader

func NewCellReader(r io.Reader, logger log.Logger) LegacyCellReceiver

NewCellReader builds a CellReceiver reading from r.

type Link interface {
	CellSender
	CellReceiver
	io.Closer
}

Link is a Cell communication layer.

func NewLink(s CellSender, r CellReceiver, c io.Closer) Link

type LinkProtocolVersion

type LinkProtocolVersion uint16

LinkProtocolVersion represents the version number of the link protocol.

var (
	// LinkProtocolNone is an empty placeholder value for the
	// LinkProtocolVersion type.
	LinkProtocolNone LinkProtocolVersion
)

func ResolveVersion

func ResolveVersion(a, b []LinkProtocolVersion) (LinkProtocolVersion, error)

ResolveVersion determines the agreed link protocol given the lists supported by each side. This is the max in both sides.

Reference: https://github.com/torproject/torspec/blob/master/tor-spec.txt#L521-L527

The payload in a VERSIONS cell is a series of big-endian two-byte
integers.  Both parties MUST select as the link protocol version the
highest number contained both in the VERSIONS cell they sent and in the
versions cell they received.  If they have no such version in common,
they cannot communicate and MUST close the connection.  Either party MUST
close the connection if the versions cell is not well-formed (for example,
if it contains an odd number of bytes).

type LinkSpec

type LinkSpec struct {
	Type LinkSpecType
	Spec []byte
}

func NewLinkSpecLegacyID

func NewLinkSpecLegacyID(id []byte) LinkSpec

func NewLinkSpecTCP

func NewLinkSpecTCP(ip net.IP, port uint16) LinkSpec

func (LinkSpec) Address

func (s LinkSpec) Address() (net.Addr, error)

Address converts the LinkSpec into an address. Returns nil if that is not possible, for example in the case of LinkSpecLegacyIdentity or LinkSpecEd25519Identity.

type LinkSpecType

type LinkSpecType byte

LinkSpecType describes how to connect to the next node in a circuit.

const (
	LinkSpecTLSTCPIPv4      LinkSpecType = 0
	LinkSpecTLSTCPIPv6      LinkSpecType = 1
	LinkSpecLegacyIdentity  LinkSpecType = 2
	LinkSpecEd25519Identity LinkSpecType = 3
)

All possible LinkSpecType values.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L954-L964

Link specifiers describe the next node in the circuit and how to
connect to it. Recognized specifiers are:
   [00] TLS-over-TCP, IPv4 address
        A four-byte IPv4 address plus two-byte ORPort
   [01] TLS-over-TCP, IPv6 address
        A sixteen-byte IPv6 address plus two-byte ORPort
   [02] Legacy identity
        A 20-byte SHA1 identity fingerprint. At most one may be listed.
   [03] Ed25519 identity
        A 32-byte Ed25519 identity fingerprint. At most one may
        be listed.

func (LinkSpecType) String

func (l LinkSpecType) String() string

type Metrics

type Metrics struct {
	Connections   telemetry.ResourceMetric
	Circuits      telemetry.ResourceMetric
	Inbound       *telemetry.Bandwidth
	Outbound      *telemetry.Bandwidth
	RelayForward  *telemetry.Bandwidth
	RelayBackward *telemetry.Bandwidth
}

func NewMetrics

func NewMetrics(scope tally.Scope, l log.Logger) *Metrics

type NetInfoCell

type NetInfoCell struct {
	Timestamp       time.Time
	ReceiverAddress net.IP
	SenderAddresses []net.IP
}

NetInfoCell represents a NETINFO cell.

func NewNetInfoCell

func NewNetInfoCell(r net.IP, s []net.IP) *NetInfoCell

NewNetInfoCell builds a NetInfoCell with the given receiver and sender addresses.

func NewNetInfoCellFromAddresses

func NewNetInfoCellFromAddresses(raddr, laddr net.Addr) (*NetInfoCell, error)

func NewNetInfoCellFromConn

func NewNetInfoCellFromConn(conn net.Conn) (*NetInfoCell, error)

NewNetInfoCellFromConn constructs a NetInfoCell with local and remote addresses from conn.

func ParseNetInfoCell

func ParseNetInfoCell(c Cell) (*NetInfoCell, error)

func (NetInfoCell) Cell

func (n NetInfoCell) Cell() (Cell, error)

Cell actually constructs the cell.

type Payloaded

type Payloaded interface {
	Payload() []byte
}

type Publisher

type Publisher struct {
	Router      *Router
	Interval    time.Duration
	Authorities []string

	Logger log.Logger
}

func (*Publisher) Publish

func (p *Publisher) Publish() error

func (*Publisher) Start

func (p *Publisher) Start()

type RelayCell

type RelayCell interface {
	RelayCommand() RelayCommand
	Recognized() uint16
	StreamID() uint16
	Digest() uint32
	RelayData() ([]byte, error)
	Bytes() []byte
}

func NewRelayCell

func NewRelayCell(cmd RelayCommand, streamID uint16, data []byte) RelayCell

func NewRelayCellFromBytes

func NewRelayCellFromBytes(b []byte) RelayCell

type RelayCommand

type RelayCommand byte

RelayCommand represents a relay cell command byte.

const (
	RelayBegin                              RelayCommand = 1
	RelayData                               RelayCommand = 2
	RelayEnd                                RelayCommand = 3
	RelayConnected                          RelayCommand = 4
	RelaySendme                             RelayCommand = 5
	RelayExtend                             RelayCommand = 6
	RelayExtended                           RelayCommand = 7
	RelayTruncate                           RelayCommand = 8
	RelayTruncated                          RelayCommand = 9
	RelayDrop                               RelayCommand = 10
	RelayResolve                            RelayCommand = 11
	RelayResolved                           RelayCommand = 12
	RelayBeginDir                           RelayCommand = 13
	RelayExtend2                            RelayCommand = 14
	RelayExtended2                          RelayCommand = 15
	RelayHiddenServiceEstablishIntro        RelayCommand = 32
	RelayHiddenServiceEstablishRendezvous   RelayCommand = 33
	RelayHiddenServiceIntroduce1            RelayCommand = 34
	RelayHiddenServiceIntroduce2            RelayCommand = 35
	RelayHiddenServiceRendezvous1           RelayCommand = 36
	RelayHiddenServiceRendezvous2           RelayCommand = 37
	RelayHiddenServiceIntroEstablished      RelayCommand = 38
	RelayHiddenServiceRendezvousEstablished RelayCommand = 39
	RelayHiddenServiceIntroduceAck          RelayCommand = 40
)

All possible RelayCommand values.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L1422-L1439

The relay commands are:
      1 -- RELAY_BEGIN     [forward]
      2 -- RELAY_DATA      [forward or backward]
      3 -- RELAY_END       [forward or backward]
      4 -- RELAY_CONNECTED [backward]
      5 -- RELAY_SENDME    [forward or backward] [sometimes control]
      6 -- RELAY_EXTEND    [forward]             [control]
      7 -- RELAY_EXTENDED  [backward]            [control]
      8 -- RELAY_TRUNCATE  [forward]             [control]
      9 -- RELAY_TRUNCATED [backward]            [control]
     10 -- RELAY_DROP      [forward or backward] [control]
     11 -- RELAY_RESOLVE   [forward]
     12 -- RELAY_RESOLVED  [backward]
     13 -- RELAY_BEGIN_DIR [forward]
     14 -- RELAY_EXTEND2   [forward]             [control]
     15 -- RELAY_EXTENDED2 [backward]            [control]

     32..40 -- Used for hidden services; see rend-spec.txt.

Reference: https://github.com/torproject/torspec/blob/0fd44031bfd6c6c822bfb194e54a05118c9625e2/rend-spec-v3.txt#L252-L307

0.5. Assigned relay cell types

   These relay cell types are reserved for use in the hidden service
   protocol.

      32 -- RELAY_COMMAND_ESTABLISH_INTRO

            Sent from hidden service host to introduction point;
            establishes introduction point. Discussed in
            [REG_INTRO_POINT].

      33 -- RELAY_COMMAND_ESTABLISH_RENDEZVOUS

            Sent from client to rendezvous point; creates rendezvous
            point. Discussed in [EST_REND_POINT].

      34 -- RELAY_COMMAND_INTRODUCE1

            Sent from client to introduction point; requests
            introduction. Discussed in [SEND_INTRO1]

      35 -- RELAY_COMMAND_INTRODUCE2

            Sent from introduction point to hidden service host; requests
            introduction. Same format as INTRODUCE1. Discussed in
            [FMT_INTRO1] and [PROCESS_INTRO2]

      36 -- RELAY_COMMAND_RENDEZVOUS1

            Sent from hidden service host to rendezvous point;
            attempts to join host's circuit to
            client's circuit. Discussed in [JOIN_REND]

      37 -- RELAY_COMMAND_RENDEZVOUS2

            Sent from rendezvous point to client;
            reports join of host's circuit to
            client's circuit. Discussed in [JOIN_REND]

      38 -- RELAY_COMMAND_INTRO_ESTABLISHED

            Sent from introduction point to hidden service host;
            reports status of attempt to establish introduction
            point. Discussed in [INTRO_ESTABLISHED]

      39 -- RELAY_COMMAND_RENDEZVOUS_ESTABLISHED

            Sent from rendezvous point to client; acknowledges
            receipt of ESTABLISH_RENDEZVOUS cell. Discussed in
            [EST_REND_POINT]

      40 -- RELAY_COMMAND_INTRODUCE_ACK

            Sent from introduction point to client; acknowledges
            receipt of INTRODUCE1 cell and reports success/failure.
            Discussed in [INTRO_ACK]

func (RelayCommand) String

func (r RelayCommand) String() string

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router is a Tor router.

func NewRouter

func NewRouter(config *torconfig.Config, scope tally.Scope, logger log.Logger) (*Router, error)

NewRouter constructs a router based on the given config.

func (*Router) Connect

func (r *Router) Connect(raddr string) (*Connection, error)

func (*Router) Connection

func (r *Router) Connection(hint ConnectionHint) (*Connection, error)

Connection returns a connection to the indicated relay. Returns an existing connection, if it exists. Otherwise opens a connection and returns it.

func (*Router) Descriptor

func (r *Router) Descriptor() (*tordir.ServerDescriptor, error)

Descriptor returns a server descriptor for this router.

func (*Router) Fingerprint

func (r *Router) Fingerprint() []byte

Fingerprint returns the router fingerprint.

func (*Router) IdentityKey

func (r *Router) IdentityKey() *rsa.PrivateKey

IdentityKey returns the identity key of the router.

func (*Router) Serve

func (r *Router) Serve() error

Serve starts a listener and enters a main loop handling connections.

type SenderManager

type SenderManager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

SenderManager manages a collection of cell senders.

func NewSenderManager

func NewSenderManager(outbound bool) *SenderManager

func (*SenderManager) Add

func (*SenderManager) AddWithID

func (m *SenderManager) AddWithID(id CircID, sc CellSenderCloser) error

func (*SenderManager) Empty

func (m *SenderManager) Empty() []CellSenderCloser

func (*SenderManager) Remove

func (m *SenderManager) Remove(id CircID) error

func (*SenderManager) Sender

func (m *SenderManager) Sender(id CircID) (CellSender, bool)

type ServerHandshakeDataNTOR

type ServerHandshakeDataNTOR []byte

ServerHandshakeDataNTOR represents server handshake data for the NTOR handshake.

Reference: https://github.com/torproject/torspec/blob/8aaa36d1a062b20ca263b6ac613b77a3ba1eb113/tor-spec.txt#L1108-L1110

The server's handshake reply is:
    SERVER_PK   Y                       [G_LENGTH bytes]
    AUTH        H(auth_input, t_mac)    [H_LENGTH bytes]

func NewServerHandshakeDataNTOR

func NewServerHandshakeDataNTOR(Y [32]byte, auth []byte) ServerHandshakeDataNTOR

type StreamCloseReason

type StreamCloseReason byte

StreamCloseReason specifies why a stream was closed.

const (
	StreamCloseReasonMisc           StreamCloseReason = 1
	StreamCloseReasonResolvefailed  StreamCloseReason = 2
	StreamCloseReasonConnectrefused StreamCloseReason = 3
	StreamCloseReasonExitpolicy     StreamCloseReason = 4
	StreamCloseReasonDestroy        StreamCloseReason = 5
	StreamCloseReasonDone           StreamCloseReason = 6
	StreamCloseReasonTimeout        StreamCloseReason = 7
	StreamCloseReasonNoroute        StreamCloseReason = 8
	StreamCloseReasonHibernating    StreamCloseReason = 9
	StreamCloseReasonInternal       StreamCloseReason = 10
	StreamCloseReasonResourcelimit  StreamCloseReason = 11
	StreamCloseReasonConnreset      StreamCloseReason = 12
	StreamCloseReasonTorprotocol    StreamCloseReason = 13
	StreamCloseReasonNotdirectory   StreamCloseReason = 14
)

All possible StreamCloseReason values.

Reference: https://github.com/torproject/torspec/blob/0fd44031bfd6c6c822bfb194e54a05118c9625e2/tor-spec.txt#L1591-L1608

 1 -- REASON_MISC           (catch-all for unlisted reasons)
 2 -- REASON_RESOLVEFAILED  (couldn't look up hostname)
 3 -- REASON_CONNECTREFUSED (remote host refused connection) [*]
 4 -- REASON_EXITPOLICY     (OR refuses to connect to host or port)
 5 -- REASON_DESTROY        (Circuit is being destroyed)
 6 -- REASON_DONE           (Anonymized TCP connection was closed)
 7 -- REASON_TIMEOUT        (Connection timed out, or OR timed out
                             while connecting)
 8 -- REASON_NOROUTE        (Routing error while attempting to
                             contact destination)
 9 -- REASON_HIBERNATING    (OR is temporarily hibernating)
10 -- REASON_INTERNAL       (Internal error at the OR)
11 -- REASON_RESOURCELIMIT  (OR has no resources to fulfill request)
12 -- REASON_CONNRESET      (Connection was unexpectedly reset)
13 -- REASON_TORPROTOCOL    (Sent when closing connection because of
                             Tor protocol violations.)
14 -- REASON_NOTDIRECTORY   (Client sent RELAY_BEGIN_DIR to a
                             non-directory relay.)

func (StreamCloseReason) String

func (s StreamCloseReason) String() string

type TLSContext

type TLSContext struct {
	IDCert   *x509.Certificate
	LinkKey  *rsa.PrivateKey
	LinkCert *x509.Certificate
	AuthKey  *rsa.PrivateKey
	AuthCert *x509.Certificate
	// contains filtered or unexported fields
}

TLSContext manages TLS parameters for a connection.

func NewTLSContext

func NewTLSContext(idKey *rsa.PrivateKey) (*TLSContext, error)

NewTLSContext builds a TLS context for a new connection with the given identity key.

func (*TLSContext) ClientConn

func (t *TLSContext) ClientConn(conn net.Conn) *tls.Conn

ClientConn wraps an existing connection with a TLS layer configured with this context.

func (*TLSContext) ServerConn

func (t *TLSContext) ServerConn(conn net.Conn) *tls.Conn

ServerConn wraps an existing connection with a TLS layer configured with this context.

type TransverseCircuit

type TransverseCircuit struct {
	Router   *Router
	Conn     *Connection
	Metrics  *Metrics
	Forward  *CircuitCryptoState
	Backward *CircuitCryptoState

	Prev CircuitLink
	Next CircuitLink
	// contains filtered or unexported fields
}

TransverseCircuit is a circuit transiting through the relay.

func NewTransverseCircuit

func NewTransverseCircuit(conn *Connection, id CircID, fwd, back *CircuitCryptoState, l log.Logger) *TransverseCircuit

func (*TransverseCircuit) BackwardSender

func (t *TransverseCircuit) BackwardSender() CellSenderCloser

func (*TransverseCircuit) Close

func (t *TransverseCircuit) Close() error

func (*TransverseCircuit) ForwardSender

func (t *TransverseCircuit) ForwardSender() CellSenderCloser

type VersionsCell

type VersionsCell struct {
	SupportedVersions []LinkProtocolVersion
}

VersionsCell is a list of supported link protocol versions.

func ParseVersionsCell

func ParseVersionsCell(c Cell) (*VersionsCell, error)

ParseVersionsCell parses a Cell into the list of supported versions.

func (VersionsCell) Cell

func (v VersionsCell) Cell() (Cell, error)

Cell builds the cell bytes for the versions cell.

Notes

Bugs

  • NewCellEmptyPayload should use sync.Pool to allocate cell buffers.

  • NewFixedCell should use sync.Pool to allocate cell buffers.

  • cellReader.ReceiveCell allocates new buffer every time (should use sync.Pool)

  • potential infinite (or at least long) loop to find a new id

  • overflow risk

  • is logging the correct behavior

  • potential double close?

  • SSLKeyLifetime option ignored when generating certificates.

  • construction of tls.Certificate type is messy

  • SSL_OP_CIPHER_SERVER_PREFERENCE not implementated

  • SSL_MODE_RELEASE_BUFFERS not implementated

  • SSL_OP_SINGLE_DH_USE and SSL_OP_SINGLE_ECDH_USE not implementated

  • SSL_OP_NO_COMPRESSION not implementated

  • is InsecureSkipVerify the same as the tor always_accept_verify_cb.

  • certificate issued time not correctly computed

Directories

Path Synopsis
Package buf contains helpers for manipulating byte buffers.
Package buf contains helpers for manipulating byte buffers.
Package check provides error checking helpers.
Package check provides error checking helpers.
cmd
Package debug contains debugging helpers.
Package debug contains debugging helpers.
Package fork contains forks of standard library packages.
Package fork contains forks of standard library packages.
sha1
Package sha1 implements the SHA1 hash algorithm as defined in RFC 3174.
Package sha1 implements the SHA1 hash algorithm as defined in RFC 3174.
tls
Package tls partially implements TLS 1.2, as specified in RFC 5246.
Package tls partially implements TLS 1.2, as specified in RFC 5246.
tls/cipherhw
Package cipherhw exposes common functions for detecting whether hardware support for certain ciphers and authenticators is present.
Package cipherhw exposes common functions for detecting whether hardware support for certain ciphers and authenticators is present.
tls/testenv
Package testenv provides information about what functionality is available in different testing environments run by the Go team.
Package testenv provides information about what functionality is available in different testing environments run by the Go team.
Package log defines standard logging for pearl.
Package log defines standard logging for pearl.
Package meta provides versioning information.
Package meta provides versioning information.
Package ntor implements the ntor handshake.
Package ntor implements the ntor handshake.
Package protover implements types for protocol version strings.
Package protover implements types for protocol version strings.
Package telemetry provides monitoring utilities.
Package telemetry provides monitoring utilities.
expvar
Package expvar reports tally metrics to expvar.
Package expvar reports tally metrics to expvar.
logging
Package logging reports tally metrics to a logger.
Package logging reports tally metrics to a logger.
Package torconfig manages tor configuration options and serialization.
Package torconfig manages tor configuration options and serialization.
Package torcrypto provides cryptographic functions useful in tor.
Package torcrypto provides cryptographic functions useful in tor.
Package tordir implements parts of the Tor directory protocol.
Package tordir implements parts of the Tor directory protocol.
Package torexitpolicy manages Tor exit policies.
Package torexitpolicy manages Tor exit policies.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL