tailscale/control/noise/messages.go
David Anderson 0b392dbaf7 control/noise: adjust implementation to match revised spec.
Signed-off-by: David Anderson <danderson@tailscale.com>
2021-11-10 12:13:54 -08:00

88 lines
3.0 KiB
Go

// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package noise
import "encoding/binary"
const (
msgTypeInitiation = 1
msgTypeResponse = 2
msgTypeError = 3
msgTypeRecord = 4
)
// headerLen is the size of the cleartext message header that gets
// prepended to Noise messages.
//
// 2b: protocol version
// 1b: message type
// 2b: payload length (not including this header)
const headerLen = 5
func setHeader(bs []byte, version int, msgType byte, length int) {
binary.LittleEndian.PutUint16(bs[:2], uint16(version))
bs[2] = msgType
binary.LittleEndian.PutUint16(bs[3:5], uint16(length))
}
func hdrVersion(bs []byte) int { return int(binary.LittleEndian.Uint16(bs[:2])) }
func hdrType(bs []byte) byte { return bs[2] }
func hdrLen(bs []byte) int { return int(binary.LittleEndian.Uint16(bs[3:5])) }
// initiationMessage is the Noise protocol message sent from a client
// machine to a control server.
//
// 5b: header (see headerLen for fields)
// 32b: client ephemeral public key (cleartext)
// 48b: client machine public key (encrypted)
// 16b: message tag (authenticates the whole message)
type initiationMessage [101]byte
func mkInitiationMessage() initiationMessage {
var ret initiationMessage
binary.LittleEndian.PutUint16(ret[:2], protocolVersion)
ret[2] = msgTypeInitiation
binary.LittleEndian.PutUint16(ret[3:5], 96)
return ret
}
func (m *initiationMessage) Header() []byte { return m[:5] }
func (m *initiationMessage) Payload() []byte { return m[5:] }
func (m *initiationMessage) Version() int { return hdrVersion(m.Header()) }
func (m *initiationMessage) Type() byte { return hdrType(m.Header()) }
func (m *initiationMessage) Length() int { return hdrLen(m.Header()) }
func (m *initiationMessage) EphemeralPub() []byte { return m[5:37] }
func (m *initiationMessage) MachinePub() []byte { return m[37:85] }
func (m *initiationMessage) Tag() []byte { return m[85:] }
// responseMessage is the Noise protocol message sent from a control
// server to a client machine.
//
// 2b: little-endian protocol version
// 1b: message type
// 2b: little-endian size of message (not including this header)
// 32b: control ephemeral public key (cleartext)
// 16b: message tag (authenticates the whole message)
type responseMessage [53]byte
func mkResponseMessage() responseMessage {
var ret responseMessage
binary.LittleEndian.PutUint16(ret[:2], protocolVersion)
ret[2] = msgTypeResponse
binary.LittleEndian.PutUint16(ret[3:5], 48)
return ret
}
func (m *responseMessage) Header() []byte { return m[:5] }
func (m *responseMessage) Payload() []byte { return m[5:] }
func (m *responseMessage) Version() int { return hdrVersion(m.Header()) }
func (m *responseMessage) Type() byte { return hdrType(m.Header()) }
func (m *responseMessage) Length() int { return hdrLen(m.Header()) }
func (m *responseMessage) EphemeralPub() []byte { return m[5:37] }
func (m *responseMessage) Tag() []byte { return m[37:] }