Massive restructure of message addressing scheme and eliminating cruft from packet

This commit is contained in:
David Vennik
2022-12-11 22:55:17 +01:00
parent fb967eaeac
commit d0accd1f80
4 changed files with 60 additions and 75 deletions

View File

@@ -28,9 +28,6 @@ var (
// container with parameters for Reed Solomon Forward Error Correction and // container with parameters for Reed Solomon Forward Error Correction and
// contains previously seen cipher keys so the correspondent can free them. // contains previously seen cipher keys so the correspondent can free them.
type Message struct { 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 specifies the segment number of the message, 4 bytes long.
Seq uint16 Seq uint16
// Length is the number of segments in the batch // Length is the number of segments in the batch
@@ -52,75 +49,52 @@ func (p *Message) GetOverhead() int {
const Overhead = slice.Uint16Len + const Overhead = slice.Uint16Len +
slice.Uint32Len + 1 + KeyEnd slice.Uint32Len + 1 + KeyEnd
// Packets is a slice of pointers to packets. type Addresses struct {
type Packets []*Message To *address.Sender
From *prv.Key
// 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
} }
// GetOverhead returns the amount of the message that will not be part of the func Address(To *address.Sender, From *prv.Key) *Addresses {
// payload. return &Addresses{To: To, From: From}
func (ep EP) GetOverhead() int {
return Overhead
} }
const ( const (
CheckEnd = 4 CheckEnd = 4
TypeEnd = CheckEnd + 1 NonceEnd = CheckEnd + nonce.IVLen
NonceEnd = TypeEnd + nonce.IVLen
AddressEnd = NonceEnd + address.Len AddressEnd = NonceEnd + address.Len
KeyEnd = AddressEnd + pub.KeyLen KeyEnd = AddressEnd + pub.KeyLen
ForwardMessage byte = iota
ReturnMessage
) )
// Encode creates a Message, encrypts the payload using the given private from // 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 // key and the public to key, serializes the form, signs the bytes and appends
// the signature to the end. // 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 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 return
} }
nonc := nonce.New() nonc := nonce.New()
var to address.Cloaked var to address.Cloaked
to, e = ep.To.GetCloak() to, e = To.GetCloak()
Length := slice.NewUint32() Length := slice.NewUint32()
slice.EncodeUint32(Length, ep.Length) slice.EncodeUint32(Length, len(d))
// Concatenate the message pieces together into a single byte slice. // Concatenate the message pieces together into a single byte slice.
pkt = slice.Cat( pkt = slice.Cat(
// f.Nonce[:], // 16 bytes \ // f.Nonce[:], // 16 bytes \
// f.To[:], // 8 bytes | // f.To[:], // 8 bytes |
make([]byte, KeyEnd), make([]byte, KeyEnd),
Length, // 4 bytes Length, // 4 bytes
ep.Data, d,
) )
// Encrypt the encrypted part of the data. // Encrypt the encrypted part of the data.
ciph.Encipher(blk, nonc, pkt[KeyEnd:]) ciph.Encipher(blk, nonc, pkt[KeyEnd:])
// Sign the packet. // Sign the packet.
var pubKey pub.Bytes var pubKey pub.Bytes
pubKey = pub.Derive(ep.From).ToBytes() pubKey = pub.Derive(From).ToBytes()
pkt[CheckEnd] = ep.Type
// Copy nonce, address, check and signature over top of the header. // 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[NonceEnd:AddressEnd], to[:])
copy(pkt[AddressEnd:KeyEnd], pubKey[:]) copy(pkt[AddressEnd:KeyEnd], pubKey[:])
// last bot not least, the packet check header, which protects the // 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 // Trim off the signature and hash, we already have the key and have
// validated the checksum. // validated the checksum.
f = &Message{Type: d[CheckEnd]} f = &Message{}
// copy the nonce // copy the nonce
var nonc nonce.IV var nonc nonce.IV
copy(nonc[:], d[TypeEnd:NonceEnd]) copy(nonc[:], d[CheckEnd:NonceEnd])
var blk cipher.Block var blk cipher.Block
if blk = ciph.GetBlock(to, from); check(e) { if blk = ciph.GetBlock(to, from); check(e) {
return return

View File

@@ -29,14 +29,8 @@ func TestEncode_Decode(t *testing.T) {
} }
addr := address.FromPubKey(rP) addr := address.FromPubKey(rP)
var pkt []byte var pkt []byte
params := EP{
Type: ForwardMessage, if pkt, e = Encode(addr, sp, payload); check(e) {
To: addr,
From: sp,
Data: payload,
Length: msgSize,
}
if pkt, e = Encode(params); check(e) {
t.Error(e) t.Error(e)
} }
var to address.Cloaked var to address.Cloaked

View File

@@ -1,11 +1,11 @@
package wire package wire
import ( import (
"crypto/cipher"
"net" "net"
"github.com/Indra-Labs/indra/pkg/ifc" "github.com/Indra-Labs/indra/pkg/ifc"
"github.com/Indra-Labs/indra/pkg/key/pub" "github.com/Indra-Labs/indra/pkg/key/pub"
"github.com/Indra-Labs/indra/pkg/message"
"github.com/Indra-Labs/indra/pkg/nonce" "github.com/Indra-Labs/indra/pkg/nonce"
) )
@@ -15,10 +15,6 @@ const MagicLen = 3
type MessageMagic string type MessageMagic string
func GetMagic(s string) (mm MessageMagic) {
return MessageMagic(s[:MagicLen])
}
type Message interface { type Message interface {
Encode() (o ifc.Message) Encode() (o ifc.Message)
} }
@@ -34,17 +30,18 @@ var (
// Forward is just an IP address and a wrapper for another message. // Forward is just an IP address and a wrapper for another message.
type Forward struct { type Forward struct {
cipher.Block *message.Addresses
net.IP net.IP
Message Message
} }
func (rm *Forward) Encode() (o ifc.Message) { func (fw *Forward) Encode() (o ifc.Message) {
ipLen := len(rm.IP) ipLen := len(fw.IP)
msg := rm.Message.Encode() msg := fw.Message.Encode()
msg, _ = message.Encode(fw.To, fw.From, msg)
fwd := make([]byte, ipLen+1) fwd := make([]byte, ipLen+1)
fwd[0] = byte(ipLen) fwd[0] = byte(ipLen)
copy(fwd[1:], rm.IP) copy(fwd[1:], fw.IP)
o = append(append(ifc.Message(ForwardMagic), fwd...), msg...) o = append(append(ifc.Message(ForwardMagic), fwd...), msg...)
return 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 // Exit messages are the layer of a message after two Forward packets that
// provides an exit address and // provides an exit address and
type Exit struct { type Exit struct {
cipher.Block *message.Addresses
// Port identifies the type of service as well as being the port used // 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 // by the service to be relayed to. Notice there is no IP address, this
// is because Indranet only forwards to exits of decentralised services // is because Indranet only forwards to exits of decentralised services
@@ -74,7 +71,9 @@ type Exit struct {
Message 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 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 // encrypting the first 16 bytes of the header and if one of the magic bytes is
// not found // not found
type Return struct { type Return struct {
cipher.Block *message.Addresses
nonce.ID nonce.ID
// IP is the address of the next relay in the return leg of a circuit. // IP is the address of the next relay in the return leg of a circuit.
net.IP net.IP
Message 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 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 // 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. // from but allows a Return public key to be provided for a Purchase.
type Cipher struct { type Cipher struct {
cipher.Block *message.Addresses
nonce.ID nonce.ID
Key pub.Bytes Key pub.Bytes
Forward 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 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 // 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. // more Return layers for carrying the Session back to the client.
type Purchase struct { type Purchase struct {
cipher.Block *message.Addresses
Bytes int Bytes int
Receipt ifc.Message Receipt ifc.Message
Return 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 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 // relay that issues a Session, ensuring that the Exit cannot see the inner
// layers of the Return messages. // layers of the Return messages.
type Session struct { type Session struct {
cipher.Block *message.Addresses
ForwardKey pub.Bytes ForwardKey pub.Bytes
ReturnKey pub.Bytes ReturnKey pub.Bytes
Return 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 return
} }
func DecodeSession(msg ifc.Message) (rm *Session, e error) { func DecodeSession(msg ifc.Message) (rm *Session, e error) {
return 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
}

View File

@@ -13,11 +13,11 @@ var (
// GitRef is the gitref, as in refs/heads/branchname. // GitRef is the gitref, as in refs/heads/branchname.
GitRef = "refs/heads/main" GitRef = "refs/heads/main"
// ParentGitCommit is the commit hash of the parent HEAD. // ParentGitCommit is the commit hash of the parent HEAD.
ParentGitCommit = "94f170b7663d743c9c50335024d42590750f0a69" ParentGitCommit = "a40766089d9ead6c8b7ed52a500aa5f91c72b882"
// BuildTime stores the time when the current binary was built. // 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 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 is the path base returned from runtime caller.
PathBase = "/home/loki/src/github.com/Indra-Labs/indra/" PathBase = "/home/loki/src/github.com/Indra-Labs/indra/"
// Major is the major number from the tag. // Major is the major number from the tag.
@@ -25,7 +25,7 @@ var (
// Minor is the minor number from the tag. // Minor is the minor number from the tag.
Minor = 0 Minor = 0
// Patch is the patch version number from the tag. // Patch is the patch version number from the tag.
Patch = 181 Patch = 182
) )
// Version returns a pretty printed version information string. // Version returns a pretty printed version information string.