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) }