Files
indra/pkg/relay/onion-sendexit.go
2023-02-22 17:10:38 +00:00

51 lines
1.9 KiB
Go

package relay
import (
"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/key/signer"
"git-indra.lan/indra-labs/indra/pkg/crypto/nonce"
"git-indra.lan/indra-labs/indra/pkg/util/slice"
)
// SendExit constructs a message containing an arbitrary payload to a node (3rd
// hop) with a set of 3 ciphers derived from the hidden PayloadPub of the return
// hops that are layered progressively after the Exit message.
//
// The Exit node forwards the packet it receives to the local port specified in
// the Exit message, and then uses the ciphers to encrypt the reply with the
// three ciphers provided, which don't enable it to decrypt the header, only to
// encrypt the payload.
//
// The response is encrypted with the given layers, the ciphers are already
// given in reverse order, so they are decoded in given order to create the
// correct payload encryption to match the PayloadPub combined with the header's
// given public From key.
//
// The header remains a constant size and each node in the Reverse trims off
// their section at the top, moves the next crypt header to the top and pads the
// remainder with noise, so it always looks like the first hop.
func SendExit(port uint16, payload slice.Bytes, id nonce.ID,
client *Session, s Circuit, ks *signer.KeySet) Skins {
var prvs [3]*prv.Key
for i := range prvs {
prvs[i] = ks.Next()
}
n := GenNonces(6)
var returnNonces [3]nonce.IV
copy(returnNonces[:], n[3:])
var pubs [3]*pub.Key
pubs[0] = s[3].PayloadPub
pubs[1] = s[4].PayloadPub
pubs[2] = client.PayloadPub
return Skins{}.
ReverseCrypt(s[0], ks.Next(), n[0], 3).
ReverseCrypt(s[1], ks.Next(), n[1], 2).
ReverseCrypt(s[2], ks.Next(), n[2], 1).
Exit(port, prvs, pubs, returnNonces, id, payload).
ReverseCrypt(s[3], prvs[0], n[3], 3).
ReverseCrypt(s[4], prvs[1], n[4], 2).
ReverseCrypt(client, prvs[2], n[5], 1)
}