Massive restructure of message addressing scheme and eliminating cruft from packet
This commit is contained in:
@@ -28,9 +28,6 @@ var (
|
||||
// container with parameters for Reed Solomon Forward Error Correction and
|
||||
// contains previously seen cipher keys so the correspondent can free them.
|
||||
type Message struct {
|
||||
// Type is the type of message, Forward or Return, and for future
|
||||
// expansion can also carry a code to specify a different cipher mode.
|
||||
Type byte
|
||||
// Seq specifies the segment number of the message, 4 bytes long.
|
||||
Seq uint16
|
||||
// Length is the number of segments in the batch
|
||||
@@ -52,75 +49,52 @@ func (p *Message) GetOverhead() int {
|
||||
const Overhead = slice.Uint16Len +
|
||||
slice.Uint32Len + 1 + KeyEnd
|
||||
|
||||
// Packets is a slice of pointers to packets.
|
||||
type Packets []*Message
|
||||
|
||||
// sort.Interface implementation.
|
||||
|
||||
func (p Packets) Len() int { return len(p) }
|
||||
func (p Packets) Less(i, j int) bool { return p[i].Seq < p[j].Seq }
|
||||
func (p Packets) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// EP defines the parameters for creating a (split) packet given a set of keys,
|
||||
// cipher, and data. To, From, Blk and Data are required, Parity is optional,
|
||||
// set it to define a level of Reed Solomon redundancy on the split packets.
|
||||
// Seen should be populated to send a signal to the other side of keys that have
|
||||
// been seen at time of constructing this packet that can now be discarded as
|
||||
// they will not be used to generate a cipher again.
|
||||
type EP struct {
|
||||
Type byte
|
||||
To *address.Sender
|
||||
From *prv.Key
|
||||
Length int
|
||||
Data []byte
|
||||
type Addresses struct {
|
||||
To *address.Sender
|
||||
From *prv.Key
|
||||
}
|
||||
|
||||
// GetOverhead returns the amount of the message that will not be part of the
|
||||
// payload.
|
||||
func (ep EP) GetOverhead() int {
|
||||
return Overhead
|
||||
func Address(To *address.Sender, From *prv.Key) *Addresses {
|
||||
return &Addresses{To: To, From: From}
|
||||
}
|
||||
|
||||
const (
|
||||
CheckEnd = 4
|
||||
TypeEnd = CheckEnd + 1
|
||||
NonceEnd = TypeEnd + nonce.IVLen
|
||||
NonceEnd = CheckEnd + nonce.IVLen
|
||||
AddressEnd = NonceEnd + address.Len
|
||||
KeyEnd = AddressEnd + pub.KeyLen
|
||||
|
||||
ForwardMessage byte = iota
|
||||
ReturnMessage
|
||||
)
|
||||
|
||||
// Encode creates a Message, encrypts the payload using the given private from
|
||||
// key and the public to key, serializes the form, signs the bytes and appends
|
||||
// the signature to the end.
|
||||
func Encode(ep EP) (pkt []byte, e error) {
|
||||
func Encode(To *address.Sender, From *prv.Key, d []byte) (pkt []byte,
|
||||
e error) {
|
||||
|
||||
var blk cipher.Block
|
||||
if blk = ciph.GetBlock(ep.From, ep.To.Key); check(e) {
|
||||
if blk = ciph.GetBlock(From, To.Key); check(e) {
|
||||
return
|
||||
}
|
||||
nonc := nonce.New()
|
||||
var to address.Cloaked
|
||||
to, e = ep.To.GetCloak()
|
||||
to, e = To.GetCloak()
|
||||
Length := slice.NewUint32()
|
||||
slice.EncodeUint32(Length, ep.Length)
|
||||
slice.EncodeUint32(Length, len(d))
|
||||
// Concatenate the message pieces together into a single byte slice.
|
||||
pkt = slice.Cat(
|
||||
// f.Nonce[:], // 16 bytes \
|
||||
// f.To[:], // 8 bytes |
|
||||
make([]byte, KeyEnd),
|
||||
Length, // 4 bytes
|
||||
ep.Data,
|
||||
d,
|
||||
)
|
||||
// Encrypt the encrypted part of the data.
|
||||
ciph.Encipher(blk, nonc, pkt[KeyEnd:])
|
||||
// Sign the packet.
|
||||
var pubKey pub.Bytes
|
||||
pubKey = pub.Derive(ep.From).ToBytes()
|
||||
pkt[CheckEnd] = ep.Type
|
||||
pubKey = pub.Derive(From).ToBytes()
|
||||
// Copy nonce, address, check and signature over top of the header.
|
||||
copy(pkt[TypeEnd:NonceEnd], nonc[:])
|
||||
copy(pkt[CheckEnd:NonceEnd], nonc[:])
|
||||
copy(pkt[NonceEnd:AddressEnd], to[:])
|
||||
copy(pkt[AddressEnd:KeyEnd], pubKey[:])
|
||||
// last bot not least, the packet check header, which protects the
|
||||
@@ -179,10 +153,10 @@ func Decode(d []byte, from *pub.Key, to *prv.Key) (f *Message, e error) {
|
||||
// Trim off the signature and hash, we already have the key and have
|
||||
// validated the checksum.
|
||||
|
||||
f = &Message{Type: d[CheckEnd]}
|
||||
f = &Message{}
|
||||
// copy the nonce
|
||||
var nonc nonce.IV
|
||||
copy(nonc[:], d[TypeEnd:NonceEnd])
|
||||
copy(nonc[:], d[CheckEnd:NonceEnd])
|
||||
var blk cipher.Block
|
||||
if blk = ciph.GetBlock(to, from); check(e) {
|
||||
return
|
||||
|
||||
@@ -29,14 +29,8 @@ func TestEncode_Decode(t *testing.T) {
|
||||
}
|
||||
addr := address.FromPubKey(rP)
|
||||
var pkt []byte
|
||||
params := EP{
|
||||
Type: ForwardMessage,
|
||||
To: addr,
|
||||
From: sp,
|
||||
Data: payload,
|
||||
Length: msgSize,
|
||||
}
|
||||
if pkt, e = Encode(params); check(e) {
|
||||
|
||||
if pkt, e = Encode(addr, sp, payload); check(e) {
|
||||
t.Error(e)
|
||||
}
|
||||
var to address.Cloaked
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"net"
|
||||
|
||||
"github.com/Indra-Labs/indra/pkg/ifc"
|
||||
"github.com/Indra-Labs/indra/pkg/key/pub"
|
||||
"github.com/Indra-Labs/indra/pkg/message"
|
||||
"github.com/Indra-Labs/indra/pkg/nonce"
|
||||
)
|
||||
|
||||
@@ -15,10 +15,6 @@ const MagicLen = 3
|
||||
|
||||
type MessageMagic string
|
||||
|
||||
func GetMagic(s string) (mm MessageMagic) {
|
||||
return MessageMagic(s[:MagicLen])
|
||||
}
|
||||
|
||||
type Message interface {
|
||||
Encode() (o ifc.Message)
|
||||
}
|
||||
@@ -34,17 +30,18 @@ var (
|
||||
|
||||
// Forward is just an IP address and a wrapper for another message.
|
||||
type Forward struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
net.IP
|
||||
Message
|
||||
}
|
||||
|
||||
func (rm *Forward) Encode() (o ifc.Message) {
|
||||
ipLen := len(rm.IP)
|
||||
msg := rm.Message.Encode()
|
||||
func (fw *Forward) Encode() (o ifc.Message) {
|
||||
ipLen := len(fw.IP)
|
||||
msg := fw.Message.Encode()
|
||||
msg, _ = message.Encode(fw.To, fw.From, msg)
|
||||
fwd := make([]byte, ipLen+1)
|
||||
fwd[0] = byte(ipLen)
|
||||
copy(fwd[1:], rm.IP)
|
||||
copy(fwd[1:], fw.IP)
|
||||
o = append(append(ifc.Message(ForwardMagic), fwd...), msg...)
|
||||
return
|
||||
|
||||
@@ -57,7 +54,7 @@ func DecodeForward(msg ifc.Message) (rm *Forward, e error) {
|
||||
// Exit messages are the layer of a message after two Forward packets that
|
||||
// provides an exit address and
|
||||
type Exit struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
// Port identifies the type of service as well as being the port used
|
||||
// by the service to be relayed to. Notice there is no IP address, this
|
||||
// is because Indranet only forwards to exits of decentralised services
|
||||
@@ -74,7 +71,9 @@ type Exit struct {
|
||||
Message
|
||||
}
|
||||
|
||||
func (rm *Exit) Encode() (o ifc.Message) {
|
||||
func (ex *Exit) Encode() (o ifc.Message) {
|
||||
msg := ex.Message.Encode()
|
||||
msg, _ = message.Encode(ex.To, ex.From, msg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,14 +86,16 @@ func DecodeExit(msg ifc.Message) (rm *Exit, e error) {
|
||||
// encrypting the first 16 bytes of the header and if one of the magic bytes is
|
||||
// not found
|
||||
type Return struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
nonce.ID
|
||||
// IP is the address of the next relay in the return leg of a circuit.
|
||||
net.IP
|
||||
Message
|
||||
}
|
||||
|
||||
func (rm *Return) Encode() (o ifc.Message) {
|
||||
func (rt *Return) Encode() (o ifc.Message) {
|
||||
msg := rt.Message.Encode()
|
||||
msg, _ = message.Encode(rt.To, rt.From, msg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -107,13 +108,15 @@ func DecodeReturn(msg ifc.Message) (rm *Return, e error) {
|
||||
// of Forward messages, ensuring that the node cannot discover where this comes
|
||||
// from but allows a Return public key to be provided for a Purchase.
|
||||
type Cipher struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
nonce.ID
|
||||
Key pub.Bytes
|
||||
Forward
|
||||
}
|
||||
|
||||
func (rm *Cipher) Encode() (o ifc.Message) {
|
||||
func (ci *Cipher) Encode() (o ifc.Message) {
|
||||
msg := ci.Forward.Encode()
|
||||
msg, _ = message.Encode(ci.To, ci.From, msg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -130,13 +133,15 @@ func DecodeCipher(msg ifc.Message) (rm *Cipher, e error) {
|
||||
// forwards through two hops to the router that will issue the Session, plus two
|
||||
// more Return layers for carrying the Session back to the client.
|
||||
type Purchase struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
Bytes int
|
||||
Receipt ifc.Message
|
||||
Return
|
||||
}
|
||||
|
||||
func (rm *Purchase) Encode() (o ifc.Message) {
|
||||
func (pr *Purchase) Encode() (o ifc.Message) {
|
||||
msg := pr.Return.Encode()
|
||||
msg, _ = message.Encode(pr.To, pr.From, msg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -151,16 +156,28 @@ func DecodePurchase(msg ifc.Message) (rm *Purchase, e error) {
|
||||
// relay that issues a Session, ensuring that the Exit cannot see the inner
|
||||
// layers of the Return messages.
|
||||
type Session struct {
|
||||
cipher.Block
|
||||
*message.Addresses
|
||||
ForwardKey pub.Bytes
|
||||
ReturnKey pub.Bytes
|
||||
Return
|
||||
}
|
||||
|
||||
func (rm *Session) Encode() (o ifc.Message) {
|
||||
func (se *Session) Encode() (o ifc.Message) {
|
||||
msg := se.Return.Encode()
|
||||
msg, _ = message.Encode(se.To, se.From, msg)
|
||||
return
|
||||
}
|
||||
|
||||
func DecodeSession(msg ifc.Message) (rm *Session, e error) {
|
||||
return
|
||||
}
|
||||
|
||||
type Raw struct {
|
||||
*message.Addresses
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
func (r Raw) Encode() (o ifc.Message) {
|
||||
o, _ = message.Encode(r.To, r.From, r.Bytes)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ var (
|
||||
// GitRef is the gitref, as in refs/heads/branchname.
|
||||
GitRef = "refs/heads/main"
|
||||
// ParentGitCommit is the commit hash of the parent HEAD.
|
||||
ParentGitCommit = "94f170b7663d743c9c50335024d42590750f0a69"
|
||||
ParentGitCommit = "a40766089d9ead6c8b7ed52a500aa5f91c72b882"
|
||||
// BuildTime stores the time when the current binary was built.
|
||||
BuildTime = "2022-12-11T22:02:30+01:00"
|
||||
BuildTime = "2022-12-11T22:55:17+01:00"
|
||||
// SemVer lists the (latest) git tag on the build.
|
||||
SemVer = "v0.0.181"
|
||||
SemVer = "v0.0.182"
|
||||
// PathBase is the path base returned from runtime caller.
|
||||
PathBase = "/home/loki/src/github.com/Indra-Labs/indra/"
|
||||
// Major is the major number from the tag.
|
||||
@@ -25,7 +25,7 @@ var (
|
||||
// Minor is the minor number from the tag.
|
||||
Minor = 0
|
||||
// Patch is the patch version number from the tag.
|
||||
Patch = 181
|
||||
Patch = 182
|
||||
)
|
||||
|
||||
// Version returns a pretty printed version information string.
|
||||
|
||||
Reference in New Issue
Block a user