2018-06-09 18:44:59 -05:00
|
|
|
package yggdrasil
|
|
|
|
|
|
|
|
// This file contains the version metadata struct
|
2019-11-29 11:45:02 +02:00
|
|
|
// Used in the initial connection setup and key exchange
|
2018-06-09 18:44:59 -05:00
|
|
|
// Some of this could arguably go in wire.go instead
|
|
|
|
|
2018-12-14 20:49:18 -06:00
|
|
|
import "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
|
|
|
|
2018-06-10 18:03:28 -05:00
|
|
|
// This is the version-specific metadata exchanged at the start of a connection.
|
2019-11-29 11:45:02 +02:00
|
|
|
// It must always begin with the 4 bytes "meta" and a wire formatted uint64 major version number.
|
|
|
|
// The current version also includes a minor version number, and the box/sig/link keys that need to be exchanged to open a connection.
|
2018-06-09 18:44:59 -05:00
|
|
|
type version_metadata struct {
|
|
|
|
meta [4]byte
|
|
|
|
ver uint64 // 1 byte in this version
|
|
|
|
// Everything after this point potentially depends on the version number, and is subject to change in future versions
|
|
|
|
minorVer uint64 // 1 byte in this version
|
2018-12-14 20:49:18 -06:00
|
|
|
box crypto.BoxPubKey
|
|
|
|
sig crypto.SigPubKey
|
|
|
|
link crypto.BoxPubKey
|
2018-06-09 18:44:59 -05:00
|
|
|
}
|
|
|
|
|
2018-06-10 18:03:28 -05:00
|
|
|
// Gets a base metadata with no keys set, but with the correct version numbers.
|
2018-06-09 18:44:59 -05:00
|
|
|
func version_getBaseMetadata() version_metadata {
|
|
|
|
return version_metadata{
|
|
|
|
meta: [4]byte{'m', 'e', 't', 'a'},
|
|
|
|
ver: 0,
|
2020-11-07 06:18:09 -06:00
|
|
|
minorVer: 0,
|
2018-06-09 18:44:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-27 09:42:46 -04:00
|
|
|
// Gets the length of the metadata for this version, used to know how many bytes to read from the start of a connection.
|
2018-06-09 18:44:59 -05:00
|
|
|
func version_getMetaLength() (mlen int) {
|
2018-12-14 20:49:18 -06:00
|
|
|
mlen += 4 // meta
|
2020-09-27 09:42:46 -04:00
|
|
|
mlen++ // ver, as long as it's < 127, which it is in this version
|
|
|
|
mlen++ // minorVer, as long as it's < 127, which it is in this version
|
2018-12-14 20:49:18 -06:00
|
|
|
mlen += crypto.BoxPubKeyLen // box
|
|
|
|
mlen += crypto.SigPubKeyLen // sig
|
|
|
|
mlen += crypto.BoxPubKeyLen // link
|
2018-06-09 18:44:59 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-06-10 18:03:28 -05:00
|
|
|
// Encodes version metadata into its wire format.
|
2018-06-09 18:44:59 -05:00
|
|
|
func (m *version_metadata) encode() []byte {
|
|
|
|
bs := make([]byte, 0, version_getMetaLength())
|
|
|
|
bs = append(bs, m.meta[:]...)
|
|
|
|
bs = append(bs, wire_encode_uint64(m.ver)...)
|
|
|
|
bs = append(bs, wire_encode_uint64(m.minorVer)...)
|
|
|
|
bs = append(bs, m.box[:]...)
|
|
|
|
bs = append(bs, m.sig[:]...)
|
|
|
|
bs = append(bs, m.link[:]...)
|
|
|
|
if len(bs) != version_getMetaLength() {
|
|
|
|
panic("Inconsistent metadata length")
|
|
|
|
}
|
|
|
|
return bs
|
|
|
|
}
|
|
|
|
|
2018-06-10 18:03:28 -05:00
|
|
|
// Decodes version metadata from its wire format into the struct.
|
2018-06-09 18:44:59 -05:00
|
|
|
func (m *version_metadata) decode(bs []byte) bool {
|
|
|
|
switch {
|
|
|
|
case !wire_chop_slice(m.meta[:], &bs):
|
|
|
|
return false
|
|
|
|
case !wire_chop_uint64(&m.ver, &bs):
|
|
|
|
return false
|
|
|
|
case !wire_chop_uint64(&m.minorVer, &bs):
|
|
|
|
return false
|
|
|
|
case !wire_chop_slice(m.box[:], &bs):
|
|
|
|
return false
|
|
|
|
case !wire_chop_slice(m.sig[:], &bs):
|
|
|
|
return false
|
|
|
|
case !wire_chop_slice(m.link[:], &bs):
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-06-10 18:03:28 -05:00
|
|
|
// Checks that the "meta" bytes and the version numbers are the expected values.
|
2018-06-09 18:44:59 -05:00
|
|
|
func (m *version_metadata) check() bool {
|
|
|
|
base := version_getBaseMetadata()
|
|
|
|
return base.meta == m.meta && base.ver == m.ver && base.minorVer == m.minorVer
|
|
|
|
}
|