| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 | 
							- package nebula
 
- import (
 
- 	"crypto/rand"
 
- 	"encoding/json"
 
- 	"fmt"
 
- 	"sync"
 
- 	"sync/atomic"
 
- 	"github.com/flynn/noise"
 
- 	"github.com/sirupsen/logrus"
 
- 	"github.com/slackhq/nebula/cert"
 
- 	"github.com/slackhq/nebula/noiseutil"
 
- )
 
- const ReplayWindow = 1024
 
- type ConnectionState struct {
 
- 	eKey           *NebulaCipherState
 
- 	dKey           *NebulaCipherState
 
- 	H              *noise.HandshakeState
 
- 	myCert         cert.Certificate
 
- 	peerCert       *cert.CachedCertificate
 
- 	initiator      bool
 
- 	messageCounter atomic.Uint64
 
- 	window         *Bits
 
- 	writeLock      sync.Mutex
 
- }
 
- func NewConnectionState(l *logrus.Logger, cs *CertState, crt cert.Certificate, initiator bool, pattern noise.HandshakePattern) (*ConnectionState, error) {
 
- 	var dhFunc noise.DHFunc
 
- 	switch crt.Curve() {
 
- 	case cert.Curve_CURVE25519:
 
- 		dhFunc = noise.DH25519
 
- 	case cert.Curve_P256:
 
- 		if cs.pkcs11Backed {
 
- 			dhFunc = noiseutil.DHP256PKCS11
 
- 		} else {
 
- 			dhFunc = noiseutil.DHP256
 
- 		}
 
- 	default:
 
- 		return nil, fmt.Errorf("invalid curve: %s", crt.Curve())
 
- 	}
 
- 	var ncs noise.CipherSuite
 
- 	if cs.cipher == "chachapoly" {
 
- 		ncs = noise.NewCipherSuite(dhFunc, noise.CipherChaChaPoly, noise.HashSHA256)
 
- 	} else {
 
- 		ncs = noise.NewCipherSuite(dhFunc, noiseutil.CipherAESGCM, noise.HashSHA256)
 
- 	}
 
- 	static := noise.DHKey{Private: cs.privateKey, Public: crt.PublicKey()}
 
- 	b := NewBits(ReplayWindow)
 
- 	// Clear out bit 0, we never transmit it, and we don't want it showing as packet loss
 
- 	b.Update(l, 0)
 
- 	hs, err := noise.NewHandshakeState(noise.Config{
 
- 		CipherSuite:   ncs,
 
- 		Random:        rand.Reader,
 
- 		Pattern:       pattern,
 
- 		Initiator:     initiator,
 
- 		StaticKeypair: static,
 
- 		//NOTE: These should come from CertState (pki.go) when we finally implement it
 
- 		PresharedKey:          []byte{},
 
- 		PresharedKeyPlacement: 0,
 
- 	})
 
- 	if err != nil {
 
- 		return nil, fmt.Errorf("NewConnectionState: %s", err)
 
- 	}
 
- 	// The queue and ready params prevent a counter race that would happen when
 
- 	// sending stored packets and simultaneously accepting new traffic.
 
- 	ci := &ConnectionState{
 
- 		H:         hs,
 
- 		initiator: initiator,
 
- 		window:    b,
 
- 		myCert:    crt,
 
- 	}
 
- 	// always start the counter from 2, as packet 1 and packet 2 are handshake packets.
 
- 	ci.messageCounter.Add(2)
 
- 	return ci, nil
 
- }
 
- func (cs *ConnectionState) MarshalJSON() ([]byte, error) {
 
- 	return json.Marshal(m{
 
- 		"certificate":     cs.peerCert,
 
- 		"initiator":       cs.initiator,
 
- 		"message_counter": cs.messageCounter.Load(),
 
- 	})
 
- }
 
- func (cs *ConnectionState) Curve() cert.Curve {
 
- 	return cs.myCert.Curve()
 
- }
 
 
  |