51 lines
1.9 KiB
Go
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)
|
|
}
|