diff --git a/docs/hiddenservice-protocol.md b/docs/hiddenservice-protocol.md new file mode 100644 index 00000000..1554f68a --- /dev/null +++ b/docs/hiddenservice-protocol.md @@ -0,0 +1,56 @@ +# Hidden Service Message Protocol + +## Creating a hidden service + +```sequence +Note left of alice: return header A -> +Note left of alice: hidden service -> +alice-->bob: relay +bob-->charlie: relay +charlie-->dave: relay +note right of dave: <-introducer +note left of dave: return header A <- +dave-->charlie: gossip intro +dave-->eve: gossip intro +dave-->bob: gossip intro +``` +## Requesting connection from introducer + +```sequence +Note left of eve: return header B -> +eve-->dave: routing request +Note left of dave: -> return header A +dave-->charlie: relay +charlie-->bob: relay +bob-->alice: relay +note right of alice: <- return header B +alice-->bob: ready +note left of alice: return header C <- +bob-->charlie: +charlie-->eve: +note left of eve: return header C -> +``` +## Request/Response Cycle + +```sequence +note left of eve: return header C -> +Note left of eve: request message -> +Note right of eve: -> return header D +eve-->charlie: return onion +charlie-->bob: return onion +bob-->alice: return onion +Note right of alice: <- return header D +Note left of alice: reply message <- +note left of alice: return header E <- +alice-->bob: next request... +bob-->charlie: +note right of eve: <- return header E +charlie-->eve: +note left of eve: new request message -> +note left of eve: return header F -> +eve-->charlie: etc +charlie-->bob: etc +bob-->alice: and so on + +``` + diff --git a/pkg/engine/hiddenroute.go b/pkg/engine/hiddenroute.go index 1f536895..54dd16ce 100644 --- a/pkg/engine/hiddenroute.go +++ b/pkg/engine/hiddenroute.go @@ -19,23 +19,19 @@ func init() { Register(HiddenRouteMagic, HiddenRoutePrototype) } type HiddenRoute struct { *pub.Key - recv *pub.Key - Cloak cloak.PubKey Onion } -func (o Skins) HiddenRoute(addr, recv *pub.Key) Skins { +func (o Skins) HiddenRoute(addr *pub.Key) Skins { return append(o, &HiddenRoute{ - Key: addr, - recv: recv, - Cloak: cloak.GetCloak(recv), + Key: addr, }) } func (x *HiddenRoute) Magic() string { return HiddenRouteMagic } func (x *HiddenRoute) Encode(s *octet.Splice) (e error) { - s.Magic(HiddenRouteMagic).Pubkey(x.Key).Cloak(x.recv) + s.Magic(HiddenRouteMagic).Pubkey(x.Key) if x.Onion != nil { return x.Onion.Encode(s) } @@ -46,8 +42,7 @@ func (x *HiddenRoute) Decode(s *octet.Splice) (e error) { if e = magic.TooShort(s.Remaining(), HiddenRouteLen-magic.Len, HiddenRouteMagic); check(e) { - s.ReadPubkey(&x.Key). - ReadCloak(&x.Cloak) + s.ReadPubkey(&x.Key) return } return @@ -64,9 +59,9 @@ func (x *HiddenRoute) Handle(s *octet.Splice, p Onion, return } -func MakeHiddenRoute(addr, recv *pub.Key, header slice.Bytes, +func MakeHiddenRoute(addr *pub.Key, header slice.Bytes, r *Routing) (o Skins) { - o = o.Triple(header).HiddenRoute(addr, recv).RoutingHeader(r) + o = o.Triple(header).HiddenRoute(addr).RoutingHeader(r) return } diff --git a/pkg/engine/route.go b/pkg/engine/route.go index c27b638b..d21db23c 100644 --- a/pkg/engine/route.go +++ b/pkg/engine/route.go @@ -10,6 +10,7 @@ import ( "git-indra.lan/indra-labs/indra/pkg/crypto/sha256" "git-indra.lan/indra-labs/indra/pkg/engine/magic" "git-indra.lan/indra-labs/indra/pkg/util/octet" + "git-indra.lan/indra-labs/indra/pkg/util/slice" ) const ( @@ -22,7 +23,10 @@ func RoutePrototype() Onion { return &Route{} } func init() { Register(RouteMagic, RoutePrototype) } type Route struct { - HiddenService, Receiver *pub.Key + HiddenService *pub.Key + // Header is the 3 layer header to use with the following cipher and + // nonces to package the return message. + Header slice.Bytes // Ciphers is a set of 3 symmetric ciphers that are to be used in their // given order over the reply message from the service. Ciphers [3]sha256.Hash @@ -32,10 +36,11 @@ type Route struct { Onion } -func (o Skins) Route(key, receiver *pub.Key, point *ExitPoint) Skins { +func (o Skins) Route(key *pub.Key, header slice.Bytes, + point *ExitPoint) Skins { return append(o, &Route{ HiddenService: key, - Receiver: receiver, + Header: header, Ciphers: GenCiphers(point.Keys, point.ReturnPubs), Nonces: point.Nonces, Onion: NewTmpl(), @@ -47,7 +52,7 @@ func (x *Route) Magic() string { return TmplMagic } func (x *Route) Encode(s *octet.Splice) (e error) { s.Magic(RouteMagic). Pubkey(x.HiddenService). - Pubkey(x.Receiver). + Bytes(x.Header). HashTriple(x.Ciphers). IVTriple(x.Nonces) if x.Onion != nil { @@ -62,7 +67,7 @@ func (x *Route) Decode(s *octet.Splice) (e error) { return } s.ReadPubkey(&x.HiddenService). - ReadPubkey(&x.Receiver). + ReadBytes(&x.Header). ReadHashTriple(&x.Ciphers). ReadIVTriple(&x.Nonces) return @@ -109,7 +114,7 @@ func (x *Route) Handle(s *octet.Splice, p Onion, }, Nonces: [3]nonce.IV{n[0], n[1], n[2]}, } - hr := MakeHiddenRoute(hb.Intro.Key, x.Receiver, hb.Bytes, r) + hr := MakeHiddenRoute(hb.Intro.Key, hb.Bytes, r) ob := hr.Assemble() encoded := Encode(ob) rb := FormatReply(hb.Bytes.ToBytes(), encoded.GetRange(-1, -1), @@ -133,17 +138,17 @@ func (x *Route) Handle(s *octet.Splice, p Onion, } } -func MakeRoute(hs, recv *pub.Key, target *SessionData, s Circuit, +func MakeRoute(hs *pub.Key, header slice.Bytes, target *SessionData, s Circuit, ks *signer.KeySet) Skins { headers := GetHeaders(target, s, ks) return Skins{}. RoutingHeader(headers.Forward). - Route(hs, recv, headers.ExitPoint()). + Route(hs, header, headers.ExitPoint()). RoutingHeader(headers.Return) } -func (ng *Engine) SendRoute(hs, recv *pub.Key, target *SessionData, - hook Callback) { +func (ng *Engine) SendRoute(hs *pub.Key, header slice.Bytes, + target *SessionData, hook Callback) { log.D.Ln("sending route", hs.ToBase32Abbreviated()) hops := StandardCircuit() @@ -152,7 +157,7 @@ func (ng *Engine) SendRoute(hs, recv *pub.Key, target *SessionData, se := ng.SelectHops(hops, s) var c Circuit copy(c[:], se) - o := MakeRoute(hs, recv, c[2], c, ng.KeySet) + o := MakeRoute(hs, header, c[2], c, ng.KeySet) log.D.Ln("sending out route request onion") res := ng.PostAcctOnion(o) ng.SendWithOneHook(c[0].AddrPort, res, hook, ng.PendingResponses) diff --git a/pkg/engine/route_test.go b/pkg/engine/route_test.go index 271c1675..e36464f3 100644 --- a/pkg/engine/route_test.go +++ b/pkg/engine/route_test.go @@ -88,7 +88,7 @@ func TestEngine_Route(t *testing.T) { // peers := clients[1:] delete(client.Introductions.KnownIntros, idPub.ToBytes()) rH := client.SessionManager.GetSessionsAtHop(2) - for i := range rH { + for _ = range rH { wg.Add(1) counter.Inc() if len(rH) > 1 { @@ -100,7 +100,6 @@ func TestEngine_Route(t *testing.T) { func(id nonce.ID, k *pub.Bytes, b slice.Bytes) (e error) { wg.Done() counter.Dec() - log.I.Ln("success", i) return }) wg.Wait()