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
|
// 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user