102 lines
2.2 KiB
Go
102 lines
2.2 KiB
Go
package jess
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/safing/jess/tools"
|
|
)
|
|
|
|
const (
|
|
wireStateInit uint8 = iota
|
|
wireStateIdle
|
|
wireStateSendKey
|
|
wireStateAwaitKey
|
|
wireStateSendApply
|
|
wireStatsAwaitApply
|
|
)
|
|
|
|
var (
|
|
// Re-exchange keys every x messages.
|
|
// At 10_000_000 msgs with 1500 bytes per msg, this would result in
|
|
// re-exchanging keys every 15 GB.
|
|
wireReKeyAfterMsgs uint64 = 10_000_000
|
|
|
|
requiredWireSessionRequirements = NewRequirements().Remove(SenderAuthentication)
|
|
)
|
|
|
|
// WireSession holds session information specific to communication over a network connection.
|
|
type WireSession struct { //nolint:maligned // TODO
|
|
session *Session
|
|
|
|
server bool
|
|
msgNo uint64
|
|
lastReKeyAtMsgNo uint64
|
|
|
|
sendKeyCarryover []byte
|
|
recvKeyCarryover []byte
|
|
|
|
// key mgmt state
|
|
eKXSignets []*kxPair
|
|
eKESignets []*kePair
|
|
handshakeState uint8
|
|
newKeyMaterial [][]byte
|
|
}
|
|
|
|
// kxPair is key exchange pair.
|
|
type kxPair struct {
|
|
tool tools.ToolLogic
|
|
signet *Signet
|
|
peer *Signet
|
|
}
|
|
|
|
// kePair is key encapsulation "pair".
|
|
type kePair struct {
|
|
tool tools.ToolLogic
|
|
signet *Signet
|
|
seal *Seal
|
|
}
|
|
|
|
// initWireSession is called after newSession() to make a wire session from a regular one.
|
|
func (s *Session) initWireSession() error {
|
|
// check required requirements
|
|
err := s.toolRequirements.CheckComplianceTo(requiredWireSessionRequirements)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// check for currently unsupported features
|
|
for _, tool := range s.all {
|
|
switch tool.Info().Purpose {
|
|
case tools.PurposePassDerivation,
|
|
tools.PurposeSigning:
|
|
return fmt.Errorf("wire sessions currently do not support %s", tool.Info().Name)
|
|
}
|
|
}
|
|
|
|
// check for static pre shared keys
|
|
err = s.envelope.LoopSecrets(SignetSchemeKey, func(signet *Signet) error {
|
|
return errors.New("wire sessions currently do not support pre-shared keys")
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.wire = &WireSession{
|
|
session: s,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Server marks a wire session as being in the role of the server, rather than the client.
|
|
func (s *Session) Server() {
|
|
if s.wire != nil {
|
|
s.wire.server = true
|
|
}
|
|
}
|
|
|
|
// reKeyNeeded returns whether rekeying is needed.
|
|
func (w *WireSession) reKeyNeeded() bool {
|
|
return w.msgNo-w.lastReKeyAtMsgNo > wireReKeyAfterMsgs
|
|
}
|