Added hidden service intro message and started test for it

This commit is contained in:
херетик
2023-02-23 11:23:36 +00:00
parent e07c495d01
commit 89f45baa0a
12 changed files with 137 additions and 29 deletions

View File

@@ -28,6 +28,7 @@ var (
// Layer exit messages are the crypt of a message after two Forward packets
// that provides an exit address and
type Layer struct {
nonce.ID
// Identity is a public key identifying the hidden service. It is encoded
// into Bech32 encoding to function like an IP address, with a 2 byte
// truncated hash check suffix to eliminate possible human input errors and
@@ -53,6 +54,7 @@ func (x *Layer) Len() int {
func (x *Layer) Encode(b slice.Bytes, c *slice.Cursor) {
splice.Splice(b, c).
Magic(Magic).
ID(x.ID).
Hash(x.Ciphers[0]).Hash(x.Ciphers[1]).Hash(x.Ciphers[2]).
IV(x.Nonces[0]).IV(x.Nonces[1]).IV(x.Nonces[2])
}
@@ -62,6 +64,7 @@ func (x *Layer) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
return magicbytes.TooShort(len(b[*c:]), Len-magicbytes.Len, string(Magic))
}
splice.Splice(b, c).
ReadID(&x.ID).
ReadHash(&x.Ciphers[0]).ReadHash(&x.Ciphers[1]).ReadHash(&x.Ciphers[2]).
ReadIV(&x.Nonces[0]).ReadIV(&x.Nonces[1]).ReadIV(&x.Nonces[2])
return

View File

@@ -5,10 +5,12 @@ import (
"sync"
"testing"
"time"
"github.com/cybriq/qu"
"go.uber.org/atomic"
"git-indra.lan/indra-labs/indra/pkg/crypto/key/prv"
"git-indra.lan/indra-labs/indra/pkg/crypto/key/pub"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/crypto/sha256"
log2 "git-indra.lan/indra-labs/indra/pkg/proc/log"
@@ -138,7 +140,7 @@ out:
}
log.I.F("success\n\n")
wg.Done()
}, 0)
})
bb := <-clients[3].ReceiveToLocalNode(port)
log.T.S(bb.ToBytes())
if e = clients[3].SendFromLocalNode(port, respMsg); check(e) {
@@ -248,3 +250,54 @@ out:
v.Shutdown()
}
}
func TestClient_HiddenService(t *testing.T) {
log2.SetLogLevel(log2.Trace)
var clients []*Engine
var e error
if clients, e = CreateNMockCircuits(true, 2, 2); check(e) {
t.Error(e)
t.FailNow()
}
// Start up the clients.
for _, v := range clients {
go v.Start()
}
quit := qu.T()
// var wg sync.WaitGroup
// go func() {
// select {
// case <-time.After(time.Second):
// case <-quit:
// return
// }
// quit.Q()
// t.Error("SendExit test failed")
// }()
var identPrv *prv.Key
if identPrv, e = prv.GenerateKey(); check(e) {
t.Error(e)
t.FailNow()
}
identPub := pub.Derive(identPrv)
out:
for i := 3; i < len(clients[0].Sessions)-1; i++ {
// wg.Add(1)
id := nonce.NewID()
clients[0].SendIntro(id, clients[0].Sessions[i],
identPub, func(id nonce.ID, b slice.Bytes) {
log.I.Ln("success")
// wg.Done()
})
select {
case <-quit:
break out
default:
}
// wg.Wait()
}
quit.Q()
for _, v := range clients {
v.Shutdown()
}
}

View File

@@ -31,7 +31,8 @@ func (p handlemessages) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func main() {
typesList := []string{"balance", "confirm", "crypt", "delay", "dxresponse",
"exit", "forward", "getbalance", "reverse", "response", "session"}
"exit", "forward", "getbalance", "hiddenservice", "reverse",
"response", "session"}
sort.Strings(typesList)
tpl := `package relay
@@ -48,6 +49,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/onion/exit"
"git-indra.lan/indra-labs/indra/pkg/onion/forward"
"git-indra.lan/indra-labs/indra/pkg/onion/getbalance"
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/onion/magicbytes"
"git-indra.lan/indra-labs/indra/pkg/onion/response"
"git-indra.lan/indra-labs/indra/pkg/onion/reverse"
@@ -97,6 +99,7 @@ func Peel(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
{"exit", true},
{"forward", true},
{"getbalance", true},
{"hiddenservice", true},
{"reverse", false},
{"response", true},
{"session", true},
@@ -115,6 +118,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/onion/exit"
"git-indra.lan/indra-labs/indra/pkg/onion/forward"
"git-indra.lan/indra-labs/indra/pkg/onion/getbalance"
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/onion/response"
"git-indra.lan/indra-labs/indra/pkg/onion/reverse"
"git-indra.lan/indra-labs/indra/pkg/onion/session"

View File

@@ -10,6 +10,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/onion/exit"
"git-indra.lan/indra-labs/indra/pkg/onion/forward"
"git-indra.lan/indra-labs/indra/pkg/onion/getbalance"
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/onion/response"
"git-indra.lan/indra-labs/indra/pkg/onion/reverse"
"git-indra.lan/indra-labs/indra/pkg/onion/session"
@@ -71,6 +72,13 @@ func (eng *Engine) handleMessage(b slice.Bytes, prev types.Onion) {
}
log.T.C(recLog(on, b, eng))
eng.getbalance(on, b, c, prev)
case *hiddenservice.Layer:
if prev == nil {
log.E.Ln(reflect.TypeOf(on), "requests from outside? absurd!")
return
}
log.T.C(recLog(on, b, eng))
eng.hiddenservice(on, b, c, prev)
case *response.Layer:
if prev == nil {
log.E.Ln(reflect.TypeOf(on), "requests from outside? absurd!")

View File

@@ -0,0 +1,12 @@
package relay
import (
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/types"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
func (eng *Engine) hiddenservice(ex *hiddenservice.Layer, b slice.Bytes,
c *slice.Cursor, prev types.Onion) {
}

View File

@@ -2,7 +2,7 @@ package relay
import (
"git-indra.lan/indra-labs/lnd/lnd/lnwire"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/onion/balance"
"git-indra.lan/indra-labs/indra/pkg/onion/confirm"
@@ -10,6 +10,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/onion/exit"
"git-indra.lan/indra-labs/indra/pkg/onion/forward"
"git-indra.lan/indra-labs/indra/pkg/onion/getbalance"
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/onion/reverse"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
@@ -59,6 +60,10 @@ func (eng *Engine) PostAcctOnion(o Skins) (res SendData) {
lnwire.MilliSatoshi(len(res.b))/1024/1024, true,
"forward")
})
case *hiddenservice.Layer:
res.last = on2.ID
res.billable = append(res.billable, s.ID)
skip = true
case *reverse.Layer:
res.billable = append(res.billable, s.ID)
case *exit.Layer:

View File

@@ -1,45 +1,38 @@
package relay
import (
"time"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
func (eng *Engine) SendExit(port uint16, message slice.Bytes, id nonce.ID,
target *Session, hook func(id nonce.ID, b slice.Bytes),
timeout time.Duration) {
func (eng *Engine) SendExit(port uint16, msg slice.Bytes, id nonce.ID,
target *Session, hook Callback) {
hops := []byte{0, 1, 2, 3, 4, 5}
s := make(Sessions, len(hops))
s[2] = target
se := eng.SelectHops(hops, s)
var c Circuit
copy(c[:], se)
o := SendExit(port, message, id, se[len(se)-1], c, eng.KeySet)
o := SendExit(port, msg, id, se[len(se)-1], c, eng.KeySet)
log.D.Ln("sending out exit onion")
res := eng.PostAcctOnion(o)
eng.SendWithOneHook(c[0].AddrPort, res, hook)
}
func (eng *Engine) MakeExit(port uint16, message slice.Bytes, id nonce.ID,
target *Session) (c Circuit,
o Skins) {
func (eng *Engine) MakeExit(port uint16, msg slice.Bytes, id nonce.ID,
exit *Session) (c Circuit, o Skins) {
hops := []byte{0, 1, 2, 3, 4, 5}
s := make(Sessions, len(hops))
s[2] = target
s[2] = exit
se := eng.SelectHops(hops, s)
copy(c[:], se)
o = SendExit(port, message, id, se[len(se)-1], c, eng.KeySet)
o = SendExit(port, msg, id, se[len(se)-1], c, eng.KeySet)
return
}
func (eng *Engine) SendExitNew(c Circuit,
o Skins, hook func(id nonce.ID, b slice.Bytes),
timeout time.Duration) {
func (eng *Engine) SendExitNew(c Circuit, o Skins, hook Callback) {
log.D.Ln("sending out exit onion")
res := eng.PostAcctOnion(o)
eng.SendWithOneHook(c[0].AddrPort, res, hook)

View File

@@ -0,0 +1,21 @@
package relay
import (
"git-indra.lan/indra-labs/indra/pkg/crypto/key/pub"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
func (eng *Engine) SendIntro(id nonce.ID, target *Session, ident *pub.Key,
hook func(id nonce.ID, b slice.Bytes)) {
hops := []byte{0, 1, 2, 3, 4, 5}
s := make(Sessions, len(hops))
s[2] = target
se := eng.SelectHops(hops, s)
var c Circuit
copy(c[:], se)
o := HiddenService(id, ident, se[len(se)-1], c, eng.KeySet)
log.D.Ln("sending out intro onion")
res := eng.PostAcctOnion(o)
eng.SendWithOneHook(c[0].AddrPort, res, hook)
}

View File

@@ -7,7 +7,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
)
func HiddenService(ident *pub.Key, client *Session, s Circuit,
func HiddenService(id nonce.ID, ident *pub.Key, client *Session, s Circuit,
ks *signer.KeySet) Skins {
var prvs [3]*prv.Key
@@ -25,7 +25,7 @@ func HiddenService(ident *pub.Key, client *Session, s Circuit,
ReverseCrypt(s[0], ks.Next(), n[0], 3).
ReverseCrypt(s[1], ks.Next(), n[1], 2).
ReverseCrypt(s[2], ks.Next(), n[2], 1).
HiddenService(ident, prvs, pubs, returnNonces).
HiddenService(id, ident, prvs, pubs, returnNonces).
ReverseCrypt(s[3], prvs[0], n[3], 3).
ReverseCrypt(s[4], prvs[1], n[4], 2).
ReverseCrypt(client, prvs[2], n[5], 1)

View File

@@ -13,6 +13,7 @@ import (
"git-indra.lan/indra-labs/indra/pkg/onion/exit"
"git-indra.lan/indra-labs/indra/pkg/onion/forward"
"git-indra.lan/indra-labs/indra/pkg/onion/getbalance"
"git-indra.lan/indra-labs/indra/pkg/onion/hiddenservice"
"git-indra.lan/indra-labs/indra/pkg/onion/magicbytes"
"git-indra.lan/indra-labs/indra/pkg/onion/response"
"git-indra.lan/indra-labs/indra/pkg/onion/reverse"
@@ -63,6 +64,11 @@ func Peel(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
if e = on.Decode(b, c); check(e) {
return
}
case hiddenservice.MagicString:
on = &hiddenservice.Layer{}
if e = on.Decode(b, c); check(e) {
return
}
case response.MagicString:
on = &response.Layer{}
if e = on.Decode(b, c); check(e) {

View File

@@ -2,7 +2,7 @@ package relay
import (
"net/netip"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
@@ -10,14 +10,16 @@ import (
// SendWithOneHook is used for onions with only one confirmation hook. Usually
// as returned from PostAcctOnion this is the last, confirmation or response
// layer in an onion.Skins.
func (eng *Engine) SendWithOneHook(ap *netip.AddrPort, res SendData, responseHook func(id nonce.ID, b slice.Bytes)) {
func (eng *Engine) SendWithOneHook(ap *netip.AddrPort, res SendData,
responseHook Callback) {
if responseHook == nil {
responseHook = func(_ nonce.ID, _ slice.Bytes) {
log.D.Ln("nil response hook")
}
}
eng.PendingResponses.Add(res.last, len(res.b), res.sessions, res.billable, res.ret, res.port, responseHook, res.postAcct)
eng.PendingResponses.Add(res.last, len(res.b), res.sessions, res.billable,
res.ret, res.port, responseHook, res.postAcct)
log.T.Ln("sending out onion")
eng.Send(ap, res.b)
}

View File

@@ -113,9 +113,10 @@ func (o Skins) GetBalance(id, confID nonce.ID, prvs [3]*prv.Key,
})
}
func (o Skins) HiddenService(addr *pub.Key, prvs [3]*prv.Key,
func (o Skins) HiddenService(id nonce.ID, addr *pub.Key, prvs [3]*prv.Key,
pubs [3]*pub.Key, nonces [3]nonce.IV) Skins {
return append(o, &hiddenservice.Layer{
ID: id,
Identity: addr,
Ciphers: GenCiphers(prvs, pubs),
Nonces: nonces,