All Decode functions implemented

This commit is contained in:
David Vennik
2022-12-23 12:28:36 +00:00
parent 8eba823930
commit 9f56a69c77
17 changed files with 180 additions and 114 deletions

View File

@@ -60,7 +60,7 @@ package client
// t.FailNow()
// }
// // Create the onion
// var lastMsg ifc.Header
// var lastMsg ifc.Message
// lastMsg, _, e = testutils.GenerateTestMessage(32)
// original := make([]byte, 32)
// copy(original, lastMsg)
@@ -70,7 +70,7 @@ package client
// // progress through the hops in reverse
// rm := &wire.HeaderKey{
// IP: ci.Hops[len(ci.Hops)-i-1].IP,
// Header: lastMsg,
// Message: lastMsg,
// }
// rmm := rm.Encode()
// ep := message.EP{
@@ -127,7 +127,7 @@ package client
// log.I.Ln("did not find matching address.Receiver")
// t.FailNow()
// }
// var f *message.Header
// var f *message.Message
// if f, e = message.Decode(lastMsg, from,
// match.Key); check(e) {
//
@@ -135,7 +135,7 @@ package client
// t.FailNow()
// }
// var rm *wire.HeaderKey
// var msg wire.Header
// var msg wire.Message
// if msg, e = wire.Deserialize(f.Data); check(e) {
// t.Error(e)
// t.FailNow()
@@ -145,9 +145,9 @@ package client
// t.FailNow()
// }
// // log.I.Ln(rm.IP)
// // log.I.S(rm.Header)
// // log.I.S(rm.Message)
// // log.I.Ln(lastMsg[0], net.IP(lastMsg[1:5]))
// lastMsg = rm.Header
// lastMsg = rm.Message
// }
// if string(original) != string(lastMsg) {
// t.Error("failed to recover original message")

View File

@@ -31,14 +31,14 @@ func GenerateKey() (prv *Key, e error) {
}
// PrivkeyFromBytes converts a byte slice into a private key.
func PrivkeyFromBytes(b Bytes) *Key {
return (*Key)(secp256k1.PrivKeyFromBytes(b[:]))
func PrivkeyFromBytes(b []byte) *Key {
return (*Key)(secp256k1.PrivKeyFromBytes(b))
}
// Zero out a private key to prevent key scraping from memory.
func (prv *Key) Zero() { (*secp256k1.PrivateKey)(prv).Zero() }
// ToBytes returns the Bytes serialized form.
// ToBytes returns the Bytes serialized form. It zeroes the original bytes.
func (prv *Key) ToBytes() (b Bytes) {
br := (*secp256k1.PrivateKey)(prv).Serialize()
copy(b[:], br[:KeyLen])

View File

@@ -134,7 +134,7 @@ func Encode(ep EP) (pkt []byte, e error) {
// After this, if the matching private key to the cloaked address returned is
// found, it is combined with the public key to generate the cipher and the
// entire packet should then be decrypted, and the Decode function will then
// decode a Header.
// decode a Message.
func GetKeys(d []byte) (from *pub.Key, e error) {
pktLen := len(d)
if pktLen < Overhead {

View File

@@ -143,6 +143,11 @@ type Bytes []byte
func ToBytes(b []byte) (msg Bytes) { return b }
func (m Bytes) ToBytes() []byte { return m }
func (m Bytes) Len() int { return len(m) }
func (m Bytes) Zero() {
for i := range m {
m[i] = 0
}
}
type U64Slice []uint64
@@ -200,6 +205,12 @@ func (u U64Slice) XOR(v U64Slice) {
}
}
func (u U64Slice) Zero() {
for i := range u[:len(u)-1] {
u[i] = 8
}
}
func (u U64Slice) ToMessage() (m Bytes) {
// length is encoded into the last element
mLen := int(u[len(u)-1])

View File

@@ -15,18 +15,23 @@ var (
check = log.E.Chk
)
// Type cipher delivers a pair of public keys to be used in association with a
// Return specifically in the situation of a node bootstrapping sessions, which
// doesn't have sessions yet.
// Type cipher delivers a pair of private keys to be used in association with a
// reply.Type specifically in the situation of a node bootstrapping sessions.
//
// After ~10 seconds these can be purged from the cache as they are otherwise a
// DoS vector buffer flooding.
//
// The Decode function wipes the original message data for security as the
// private keys inside it are no longer needed and any secret should only have
// one storage so it doesn't appear in any GC later.
type Type struct {
Header, Payload pub.Bytes
PrivHeader, PrivPayload *prv.Key
Header, Payload *prv.Key
types.Onion
}
var (
Magic = slice.Bytes("cif")
MinLen = magicbytes.Len + pub.KeyLen*2
MinLen = magicbytes.Len + prv.KeyLen*2
_ types.Onion = &Type{}
)
@@ -38,32 +43,25 @@ func (x *Type) Len() int {
func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
copy(o[*c:c.Inc(magicbytes.Len)], Magic)
hdr := pub.Derive(x.PrivHeader).ToBytes()
pld := pub.Derive(x.PrivPayload).ToBytes()
hdr := x.Header.ToBytes()
pld := x.Payload.ToBytes()
copy(o[c.Inc(1):c.Inc(pub.KeyLen)], hdr[:])
copy(o[c.Inc(1):c.Inc(pub.KeyLen)], pld[:])
x.Onion.Encode(o, c)
}
// Decode unwraps a cipher.Type message.
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
var header, payload *pub.Key
if header, e = pub.FromBytes(
b[c.Inc(magicbytes.Len):c.Inc(pub.KeyLen)]); check(e) {
// this ensures the key is on the curve.
return
}
if payload, e = pub.FromBytes(b[*c:c.Inc(pub.KeyLen)]); check(e) {
// this ensures the key is on the curve.
return
}
x.Header, x.Payload = header.ToBytes(), payload.ToBytes()
start := c.Inc(magicbytes.Len)
x.Header = prv.PrivkeyFromBytes(b[start:c.Inc(pub.KeyLen)])
x.Payload = prv.PrivkeyFromBytes(b[*c:c.Inc(pub.KeyLen)])
// zero out the version in the message as we have copied it to an array.
b[start:*c].Zero()
return
}

View File

@@ -15,14 +15,14 @@ var (
)
// Type confirmation is an encryption layer for messages returned to the client
// on the inside of an onion, for Ping and Cipher messages, providing a
// on the inside of an onion, for Ping and Ciphers messages, providing a
// confirmation of the transit of the onion through its encoded route.
//
// It is encrypted because otherwise internal identifiers could be leaked and
// potentially reveal something about the entropy of a client/relay.
//
// In order to speed up recognition, the key of the table of pending Ping and
// Cipher messages will include the last hop that will deliver this layer of the
// Ciphers messages will include the last hop that will deliver this layer of the
// onion - there can be more than one up in the air at a time, but they are
// randomly selected, so they will generally be a much smaller subset versus the
// current full set of Session s currently open.

View File

@@ -25,9 +25,9 @@ type Type struct {
// a local Socks5 proxy into Indranet and the exit node also having
// this.
Port uint16
// Cipher is a set of 3 symmetric ciphers that are to be used in their
// Ciphers is a set of 3 symmetric ciphers that are to be used in their
// given order over the reply message from the service.
Cipher [3]sha256.Hash
Ciphers [3]sha256.Hash
// Bytes are the message to be passed to the exit service.
slice.Bytes
types.Onion
@@ -51,9 +51,9 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
port := slice.NewUint16()
slice.EncodeUint16(port, int(x.Port))
copy(o[*c:c.Inc(slice.Uint16Len)], port)
copy(o[*c:c.Inc(sha256.Len)], x.Cipher[0][:])
copy(o[*c:c.Inc(sha256.Len)], x.Cipher[1][:])
copy(o[*c:c.Inc(sha256.Len)], x.Cipher[1][:])
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[0][:])
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[1][:])
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[1][:])
bytesLen := slice.NewUint32()
slice.EncodeUint32(bytesLen, len(x.Bytes))
copy(o[*c:c.Inc(slice.Uint32Len)], bytesLen)
@@ -63,13 +63,19 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
}
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
x.Port = uint16(slice.DecodeUint16(b[*c:slice.Uint16Len]))
for i := range x.Ciphers {
bytes := b[*c:c.Inc(sha256.Len)]
copy(x.Ciphers[i][:], bytes)
bytes.Zero()
}
bytesLen := slice.DecodeUint32(b[*c:c.Inc(slice.Uint32Len)])
x.Bytes = b[*c:c.Inc(bytesLen)]
return
}

View File

@@ -41,14 +41,13 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
}
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
ipLen := b[0]
x.IP = net.IP(b[1 : 1+ipLen])
ipLen := b[*c]
x.IP = net.IP(b[c.Inc(1):c.Inc(int(ipLen))])
return
}

View File

@@ -16,15 +16,15 @@ import (
"github.com/Indra-Labs/indra/pkg/wire/forward"
"github.com/Indra-Labs/indra/pkg/wire/message"
"github.com/Indra-Labs/indra/pkg/wire/purchase"
"github.com/Indra-Labs/indra/pkg/wire/reply"
"github.com/Indra-Labs/indra/pkg/wire/response"
"github.com/Indra-Labs/indra/pkg/wire/retrn"
"github.com/Indra-Labs/indra/pkg/wire/session"
"github.com/Indra-Labs/indra/pkg/wire/token"
)
type OnionSkins []types.Onion
func (o OnionSkins) Header(to *address.Sender, from *prv.Key) OnionSkins {
func (o OnionSkins) Message(to *address.Sender, from *prv.Key) OnionSkins {
return append(o, &message.Type{To: to, From: from})
}
func (o OnionSkins) Confirmation(id nonce.ID) OnionSkins {
@@ -36,13 +36,13 @@ func (o OnionSkins) Forward(ip net.IP) OnionSkins {
func (o OnionSkins) Exit(port uint16, ciphers [3]sha256.Hash,
payload slice.Bytes) OnionSkins {
return append(o, &exit.Type{Port: port, Cipher: ciphers, Bytes: payload})
return append(o, &exit.Type{Port: port, Ciphers: ciphers, Bytes: payload})
}
func (o OnionSkins) Return(ip net.IP) OnionSkins {
return append(o, &retrn.Type{IP: ip})
return append(o, &reply.Type{IP: ip})
}
func (o OnionSkins) Cipher(hdr, pld *prv.Key) OnionSkins {
return append(o, &cipher.Type{PrivHeader: hdr, PrivPayload: pld})
return append(o, &cipher.Type{Header: hdr, Payload: pld})
}
func (o OnionSkins) Purchase(nBytes uint64, ciphers [3]sha256.Hash) OnionSkins {
return append(o, &purchase.Type{NBytes: nBytes, Ciphers: ciphers})

View File

@@ -2,6 +2,7 @@ package message
import (
"crypto/cipher"
"fmt"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/ciph"
@@ -27,7 +28,15 @@ var (
type Type struct {
To *address.Sender
From *prv.Key
// The following field is only populated in the outermost layer.
// The remainder here are for Decode.
Nonce nonce.IV
Cloak address.Cloaked
ToPriv *prv.Key
FromPub *pub.Key
// The following field is only populated in the outermost layer, and
// passed in the `b slice.Bytes` parameter in both encode and decode,
// this is created after first getting the Len of everything and
// pre-allocating.
slice.Bytes
types.Onion
}
@@ -44,50 +53,54 @@ func (x *Type) Len() int {
return MinLen + x.Onion.Len()
}
func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
func (x *Type) Encode(b slice.Bytes, c *slice.Cursor) {
// The first level message contains the Bytes, but the inner layers do
// not. The inner layers will be passed this buffer, but the first needs
// to have it copied from its original location.
if o == nil {
o = x.Bytes
if b == nil {
b = x.Bytes
}
// We write the checksum last so save the cursor position here.
checkStart, checkEnd := *c, c.Inc(4)
// Magic after the check so it is part of the checksum.
copy(o[*c:c.Inc(magicbytes.Len)], Magic)
// Magic after the check, so it is part of the checksum.
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
// Generate a new nonce and copy it in.
n := nonce.New()
copy(o[c.Inc(4):c.Inc(nonce.IVLen)], n[:])
copy(b[c.Inc(4):c.Inc(nonce.IVLen)], n[:])
// Derive the cloaked key and copy it in.
to := x.To.GetCloak()
copy(o[*c:c.Inc(address.Len)], to[:])
copy(b[*c:c.Inc(address.Len)], to[:])
// Derive the public key from the From key and copy in.
pubKey := pub.Derive(x.From).ToBytes()
copy(o[*c:c.Inc(pub.KeyLen)], pubKey[:])
copy(b[*c:c.Inc(pub.KeyLen)], pubKey[:])
// Encode the remaining data size of the message below. This will also
// be the entire remaining part of the message buffer.
mLen := len(o[*c:]) - slice.Uint32Len
mLen := len(b[*c:]) - slice.Uint32Len
length := slice.NewUint32()
slice.EncodeUint32(length, mLen)
copy(o[*c:c.Inc(mLen)], o[*c:])
copy(b[*c:c.Inc(mLen)], b[*c:])
// Call the tree of onions to perform their encoding.
x.Onion.Encode(o, c)
x.Onion.Encode(b, c)
// Then we can encrypt the message segment
var e error
var blk cipher.Block
if blk = ciph.GetBlock(x.From, x.To.Key); check(e) {
panic(e)
}
ciph.Encipher(blk, n, o[MinLen:])
ciph.Encipher(blk, n, b[MinLen:])
// Get the hash of the message and truncate it to the checksum at the
// start of the message. Every layer of the onion has a Header and an
// onion inside it, the Header takes care of the encryption. This saves
// start of the message. Every layer of the onion has a Message and an
// onion inside it, the Message takes care of the encryption. This saves
// x complications as every layer is header first, message after, with
// wrapped messages inside each message afterwards.
hash := sha256.Single(o[checkEnd:])
copy(o[checkStart:checkEnd], hash[:4])
hash := sha256.Single(b[checkEnd:])
copy(b[checkStart:checkEnd], hash[:4])
}
// Decode decodes a received message. Note that it only gets the relevant data
// from the header, a subsequent process must be performed to find the prv.Key
// corresponding to the Cloak and the pub.Key together forming the cipher secret
// needed to decrypt the remainder of the bytes.
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
minLen := MinLen
if len(b) < minLen {
@@ -96,8 +109,28 @@ func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
cloak := b[*c:c.Inc(address.Len)]
_ = cloak
var n nonce.IV
copy(n[:], b[c.Inc(magicbytes.Len):c.Inc(nonce.IVLen)])
copy(x.Nonce[:], n[:])
copy(x.Cloak[:], b[*c:c.Inc(address.Len)])
if x.FromPub, e = pub.FromBytes(b[*c:c.Inc(pub.KeyLen)]); check(e) {
return
}
length := slice.DecodeUint32(b[*c:c.Inc(slice.Uint32Len)])
if length < len(b[*c:]) {
e = fmt.Errorf("not enough remaining bytes as specified in"+
" length field, got: %d expected %d",
length, len(b[*c:]))
}
// A further step is required which decrypts the remainder of the bytes
// after finding the private key corresponding to the Cloak and
// FromPubKey.
return
}
// Decrypt requires the ToPriv key to be located from the Cloak, using the
// FromPub key to derive the shared secret, and then decrypts the rest of the
// message.
func (x *Type) Decrypt(b slice.Bytes, c *slice.Cursor) {
ciph.Encipher(ciph.GetBlock(x.ToPriv, x.FromPub), x.Nonce, b[*c:])
}

View File

@@ -26,13 +26,13 @@ func Ping(id nonce.ID, client node.Node, hop [3]node.Node,
set signer.KeySet) types.Onion {
return OnionSkins{}.
Header(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Header(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Header(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Forward(client.IP).
Header(address.FromPubKey(client.HeaderKey), set.Next()).
Message(address.FromPubKey(client.HeaderKey), set.Next()).
Confirmation(id).
Assemble()
}
@@ -41,7 +41,7 @@ func Ping(id nonce.ID, client node.Node, hop [3]node.Node,
// Purchase header bytes and to generate the ciphers provided in the Purchase
// message to encrypt the Session that is returned.
//
// The Header key, its cloaked public key counterpart used in the To field of
// The Message key, its cloaked public key counterpart used in the To field of
// the Purchase message preformed header bytes, but the Ciphers provided in the
// Purchase message, for encrypting the Session to be returned, uses the Payload
// key, along with the public key found in the encrypted layer of the header for
@@ -54,18 +54,18 @@ func SendKeys(id nonce.ID, hdr, pld *prv.Key,
client node.Node, hop [5]node.Node, set signer.KeySet) types.Onion {
return OnionSkins{}.
Header(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Header(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Header(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Cipher(hdr, pld).
Forward(hop[3].IP).
Header(address.FromPubKey(hop[3].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[3].HeaderKey), set.Next()).
Forward(hop[4].IP).
Header(address.FromPubKey(hop[4].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[4].HeaderKey), set.Next()).
Forward(client.IP).
Header(address.FromPubKey(client.HeaderKey), set.Next()).
Message(address.FromPubKey(client.HeaderKey), set.Next()).
Confirmation(id).
Assemble()
}
@@ -103,18 +103,18 @@ func SendPurchase(nBytes uint64, client node.Node,
}
return OnionSkins{}.
Header(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Header(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Header(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Purchase(nBytes, ciphers).
Return(hop[3].IP).
Header(address.FromPubKey(hop[3].HeaderKey), rtns[0]).
Message(address.FromPubKey(hop[3].HeaderKey), rtns[0]).
Return(hop[4].IP).
Header(address.FromPubKey(hop[4].HeaderKey), rtns[1]).
Message(address.FromPubKey(hop[4].HeaderKey), rtns[1]).
Return(client.IP).
Header(address.FromPubKey(client.HeaderKey), rtns[2]).
Message(address.FromPubKey(client.HeaderKey), rtns[2]).
Assemble()
}
@@ -155,17 +155,17 @@ func SendExit(payload slice.Bytes, port uint16, client node.Node,
}
return OnionSkins{}.
Header(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Header(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Header(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Exit(port, ciphers, payload).
Return(hop[3].IP).
Header(address.FromPubKey(hop[3].HeaderKey), rtns[0]).
Message(address.FromPubKey(hop[3].HeaderKey), rtns[0]).
Return(hop[4].IP).
Header(address.FromPubKey(hop[4].HeaderKey), rtns[1]).
Message(address.FromPubKey(hop[4].HeaderKey), rtns[1]).
Return(client.IP).
Header(address.FromPubKey(client.HeaderKey), rtns[2]).
Message(address.FromPubKey(client.HeaderKey), rtns[2]).
Assemble()
}

View File

@@ -41,17 +41,25 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
copy(o[*c:c.Inc(magicbytes.Len)], Magic)
value := slice.NewUint64()
slice.EncodeUint64(value, x.NBytes)
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[0][:])
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[1][:])
copy(o[*c:c.Inc(sha256.Len)], x.Ciphers[1][:])
x.Onion.Encode(o, c)
}
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
x.NBytes = slice.DecodeUint64(
b[c.Inc(magicbytes.Len):c.Inc(slice.Uint64Len)])
for i := range x.Ciphers {
bytes := b[*c:c.Inc(sha256.Len)]
copy(x.Ciphers[i][:], bytes)
bytes.Zero()
}
return
}

View File

@@ -1,4 +1,4 @@
package retrn
package reply
import (
"net"
@@ -15,10 +15,12 @@ var (
check = log.E.Chk
)
// Type is return messages, distinct from Forward messages in that the header
// encryption uses a different secret than the payload. The magic bytes signal
// this to the relay that receives this, which then looks up the PayloadHey
// matching the To address in the message header.
// Type is reply messages, distinct from forward.Type messages in that the
// header encryption uses a different secret than the payload. The magic bytes
// signal this to the relay that receives this, which then looks up the
// PayloadHey matching the To address in the message header. And lastly, each
// step the relay budges up it's message to the front of the packet and puts
// csprng random bytes into the remainder to the same length.
type Type struct {
// IP is the address of the next relay in the return leg of a circuit.
net.IP
@@ -26,7 +28,7 @@ type Type struct {
}
var (
Magic = slice.Bytes("rtn")
Magic = slice.Bytes("rpl")
MinLen = magicbytes.Len + 1 + net.IPv4len
_ types.Onion = &Type{}
)
@@ -45,13 +47,13 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
}
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
ipLen := b[0]
x.IP = net.IP(b[1 : 1+ipLen])
return
}

View File

@@ -1,6 +1,9 @@
package response
import (
"reflect"
"unsafe"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/slice"
"github.com/Indra-Labs/indra/pkg/types"
@@ -29,19 +32,22 @@ func (x Response) Len() int { return MinLen + len(x) }
func (x Response) Encode(o slice.Bytes, c *slice.Cursor) {
copy(o[*c:c.Inc(magicbytes.Len)], Magic)
bytesLen := slice.NewUint32()
slice.EncodeUint32(bytesLen, len(x))
slice.EncodeUint32(bytesLen, len(x)-slice.Uint32Len)
copy(o[*c:c.Inc(slice.Uint32Len)], bytesLen)
copy(o[*c:c.Inc(len(x))], x)
}
func (x Response) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
responseLen := slice.DecodeUint32(b[*c:c.Inc(slice.Uint32Len)])
xd := Response(b[*c:c.Inc(responseLen)])
// replace current slice header using unsafe.
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&x))
hdr.Data = (*reflect.SliceHeader)(unsafe.Pointer(&xd)).Data
return
}

View File

@@ -1,8 +1,6 @@
package session
import (
"net"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/key/pub"
"github.com/Indra-Labs/indra/pkg/slice"
@@ -29,14 +27,13 @@ var (
// their generated private key which produces the public key that is placed in
// the header.
type Type struct {
HeaderKey *pub.Key
PayloadKey *pub.Key
HeaderKey, PayloadKey *pub.Key
types.Onion
}
var (
Magic = slice.Bytes("ses")
MinLen = magicbytes.Len + 1 + net.IPv4len
MinLen = magicbytes.Len + pub.KeyLen*2
_ types.Onion = &Type{}
)
@@ -55,13 +52,19 @@ func (x *Type) Encode(o slice.Bytes, c *slice.Cursor) {
}
func (x *Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if !magicbytes.CheckMagic(b, Magic) {
return magicbytes.WrongMagic(x, b, Magic)
}
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
if x.HeaderKey, e = pub.FromBytes(b[c.Inc(magicbytes.Len):c.Inc(
pub.KeyLen)]); check(e) {
return
}
if x.PayloadKey, e = pub.FromBytes(b[*c:c.Inc(pub.KeyLen)]); check(e) {
return
}
return
}

View File

@@ -40,6 +40,6 @@ func (x Type) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b) < MinLen {
return magicbytes.TooShort(len(b), MinLen, string(Magic))
}
copy(x[:], b[c.Inc(magicbytes.Len):c.Inc(sha256.Len)])
return
}

View File

@@ -11,11 +11,11 @@ var (
// URL is the git URL for the repository.
URL = "github.com/Indra-Labs/indra"
// GitRef is the gitref, as in refs/heads/branchname.
GitRef = "refs/heads/main"
GitRef = "refs/heads/ind-bootstrap"
// ParentGitCommit is the commit hash of the parent HEAD.
ParentGitCommit = "2a4c65e4671e1ff9463c494f298bcf2d7650ea97"
ParentGitCommit = "ec634cba58726396fa6aac6634f82d499e714f81"
// BuildTime stores the time when the current binary was built.
BuildTime = "2022-12-23T09:53:26Z"
BuildTime = "2022-12-23T12:28:36Z"
// SemVer lists the (latest) git tag on the build.
SemVer = "v0.0.216"
// PathBase is the path base returned from runtime caller.