2019-11-19 10:00:20 -07:00
|
|
|
package nebula
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"encoding/json"
|
|
|
|
"sync"
|
2021-03-05 19:18:33 -07:00
|
|
|
"sync/atomic"
|
2019-11-19 10:00:20 -07:00
|
|
|
|
|
|
|
"github.com/flynn/noise"
|
2021-03-26 08:46:30 -06:00
|
|
|
"github.com/sirupsen/logrus"
|
2019-11-19 10:00:20 -07:00
|
|
|
"github.com/slackhq/nebula/cert"
|
|
|
|
)
|
|
|
|
|
|
|
|
const ReplayWindow = 1024
|
|
|
|
|
|
|
|
type ConnectionState struct {
|
2021-03-05 19:18:33 -07:00
|
|
|
eKey *NebulaCipherState
|
|
|
|
dKey *NebulaCipherState
|
|
|
|
H *noise.HandshakeState
|
|
|
|
certState *CertState
|
|
|
|
peerCert *cert.NebulaCertificate
|
|
|
|
initiator bool
|
|
|
|
atomicMessageCounter uint64
|
|
|
|
window *Bits
|
|
|
|
queueLock sync.Mutex
|
|
|
|
writeLock sync.Mutex
|
|
|
|
ready bool
|
2019-11-19 10:00:20 -07:00
|
|
|
}
|
|
|
|
|
2021-03-26 08:46:30 -06:00
|
|
|
func (f *Interface) newConnectionState(l *logrus.Logger, initiator bool, pattern noise.HandshakePattern, psk []byte, pskStage int) *ConnectionState {
|
2019-11-19 10:00:20 -07:00
|
|
|
cs := noise.NewCipherSuite(noise.DH25519, noise.CipherAESGCM, noise.HashSHA256)
|
|
|
|
if f.cipher == "chachapoly" {
|
|
|
|
cs = noise.NewCipherSuite(noise.DH25519, noise.CipherChaChaPoly, noise.HashSHA256)
|
|
|
|
}
|
|
|
|
|
|
|
|
curCertState := f.certState
|
|
|
|
static := noise.DHKey{Private: curCertState.privateKey, Public: curCertState.publicKey}
|
|
|
|
|
|
|
|
b := NewBits(ReplayWindow)
|
|
|
|
// Clear out bit 0, we never transmit it and we don't want it showing as packet loss
|
2021-03-26 08:46:30 -06:00
|
|
|
b.Update(l, 0)
|
2019-11-19 10:00:20 -07:00
|
|
|
|
|
|
|
hs, err := noise.NewHandshakeState(noise.Config{
|
|
|
|
CipherSuite: cs,
|
|
|
|
Random: rand.Reader,
|
|
|
|
Pattern: pattern,
|
|
|
|
Initiator: initiator,
|
|
|
|
StaticKeypair: static,
|
|
|
|
PresharedKey: psk,
|
|
|
|
PresharedKeyPlacement: pskStage,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// The queue and ready params prevent a counter race that would happen when
|
|
|
|
// sending stored packets and simultaneously accepting new traffic.
|
|
|
|
ci := &ConnectionState{
|
2021-03-05 19:18:33 -07:00
|
|
|
H: hs,
|
|
|
|
initiator: initiator,
|
|
|
|
window: b,
|
|
|
|
ready: false,
|
|
|
|
certState: curCertState,
|
2019-11-19 10:00:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return ci
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *ConnectionState) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(m{
|
|
|
|
"certificate": cs.peerCert,
|
|
|
|
"initiator": cs.initiator,
|
2021-03-05 19:18:33 -07:00
|
|
|
"message_counter": atomic.LoadUint64(&cs.atomicMessageCounter),
|
2019-11-19 10:00:20 -07:00
|
|
|
"ready": cs.ready,
|
|
|
|
})
|
|
|
|
}
|