diff options
author | Christian Pointner <equinox@anytun.org> | 2017-11-04 21:02:27 +0100 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2017-11-04 21:02:32 +0100 |
commit | 3603a67ba4dc8c32c7130848aac7f58115b842ed (patch) | |
tree | 098264a9e5239bc90cb3c4523959a164d0882391 /satp | |
parent | nicoo insisted on fixing the typo (i don't agree with him but i changed it an... (diff) |
SA now handles sequence windows
Diffstat (limited to 'satp')
-rw-r--r-- | satp/security-association.go | 27 | ||||
-rw-r--r-- | satp/security-association_test.go | 51 |
2 files changed, 62 insertions, 16 deletions
diff --git a/satp/security-association.go b/satp/security-association.go index 3a654a6..efe581e 100644 --- a/satp/security-association.go +++ b/satp/security-association.go @@ -33,6 +33,7 @@ package satp import ( + "fmt" "net" "sync" "sync/atomic" @@ -48,7 +49,8 @@ type SecurityAssociation struct { endpoints []*net.UDPAddr nextSeqNr uint32 initialSeqNrInbound uint32 - seqWins *sync.Map + seqWindowSize uint + seqWindows *sync.Map } func (sa *SecurityAssociation) KeyGenerate(dir Direction, usage KeyUsage, sequenceNumber uint32, out []byte) error { @@ -86,22 +88,33 @@ func (sa *SecurityAssociation) GetEndpointsAndNextSequenceNumber(epsIn []*net.UD return } +func (sa *SecurityAssociation) getSequenceWindow(senderID uint16) *SequenceWindow { + win, present := sa.seqWindows.Load(senderID) + if !present { + var err error + if win, err = NewSequenceWindow(int(sa.seqWindowSize), sa.initialSeqNrInbound); err != nil { + panic(fmt.Sprint("unable to create new sequence window:", err)) // return an error instead??? + } + sa.seqWindows.Store(senderID, win) + } + return win.(*SequenceWindow) +} + func (sa *SecurityAssociation) SequenceNumberCheck(senderID uint16, sequenceNumber uint32) bool { - // TODO: implement this - return false + return sa.getSequenceWindow(senderID).Check(sequenceNumber) } func (sa *SecurityAssociation) SequenceNumberCheckAndSet(senderID uint16, sequenceNumber uint32) bool { - // TODO: implement this - return false + return sa.getSequenceWindow(senderID).CheckAndSet(sequenceNumber) } -func NewSecurityAssociation(kd KeyDerivation, numEndpoints uint, initialSeqNrOutbound, initialSeqNrInbound uint32) (sa *SecurityAssociation) { +func NewSecurityAssociation(kd KeyDerivation, numEndpoints uint, initialSeqNrOutbound, initialSeqNrInbound uint32, seqWindowSize uint) (sa *SecurityAssociation) { sa = &SecurityAssociation{kd: kd} // panic if numEndpoints == 0? sa.endpoints = make([]*net.UDPAddr, numEndpoints) sa.nextSeqNr = initialSeqNrOutbound sa.initialSeqNrInbound = initialSeqNrInbound - sa.seqWins = &sync.Map{} + sa.seqWindowSize = seqWindowSize + sa.seqWindows = &sync.Map{} return } diff --git a/satp/security-association_test.go b/satp/security-association_test.go index 2b1d3cd..bdd572f 100644 --- a/satp/security-association_test.go +++ b/satp/security-association_test.go @@ -50,7 +50,7 @@ func TestSecurityAssociationNew(t *testing.T) { } for _, vector := range testvectors { - sa := NewSecurityAssociation(nil, vector.numEndpoints, vector.initSeqOut, vector.initSeqIn) + sa := NewSecurityAssociation(nil, vector.numEndpoints, vector.initSeqOut, vector.initSeqIn, 0) if sa == nil { t.Fatal("NewSecurityAssociation returned nil") } @@ -72,7 +72,7 @@ func TestSecurityAssociationGenerate(t *testing.T) { t.Fatal("unexpected error:", err) } - sa := NewSecurityAssociation(kd, 1, 0, 0) + sa := NewSecurityAssociation(kd, 1, 0, 0, 0) var out [32]byte err = sa.KeyGenerate(Outbound, UsageEncryptKey, 23, out[:32]) @@ -136,10 +136,10 @@ func TestSecurityAssociationEndpointUpdate(t *testing.T) { addr6, _ := net.ResolveUDPAddr("udp6", "[2a02::1]:666") // should this panic?? - sa := NewSecurityAssociation(nil, 0, 0, 0) + sa := NewSecurityAssociation(nil, 0, 0, 0, 0) sa.EndpointUpdate(0, addr4) - sa = NewSecurityAssociation(nil, 1, 0, 0) + sa = NewSecurityAssociation(nil, 1, 0, 0, 0) if sa.endpoints[0] != nil { t.Fatalf("endpoints[0] is %v but should be nil", sa.endpoints[0]) } @@ -152,7 +152,7 @@ func TestSecurityAssociationEndpointUpdate(t *testing.T) { t.Fatalf("endpoints[0] is %v but should be %v", sa.endpoints[0], addr6) } - sa = NewSecurityAssociation(nil, 3, 0, 0) + sa = NewSecurityAssociation(nil, 3, 0, 0, 0) sa.EndpointUpdate(0, addr4) sa.EndpointUpdate(2, addr6) if !EndpointsEqual(sa.endpoints[0], addr4) { @@ -171,10 +171,10 @@ func TestSecurityAssociationEndpointCompareAndUpdate(t *testing.T) { addr6, _ := net.ResolveUDPAddr("udp6", "[2a01:1234::2]:666") // should this panic?? - sa := NewSecurityAssociation(nil, 0, 0, 0) + sa := NewSecurityAssociation(nil, 0, 0, 0, 0) sa.EndpointCompareAndUpdate(0, addr4) - sa = NewSecurityAssociation(nil, 1, 0, 0) + sa = NewSecurityAssociation(nil, 1, 0, 0, 0) changed := sa.EndpointCompareAndUpdate(0, addr4) if !EndpointsEqual(sa.endpoints[0], addr4) { @@ -202,7 +202,7 @@ func TestSecurityAssociationEndpointCompareAndUpdate(t *testing.T) { } func TestSecurityAssociationGetEndpointsAndNextSequenceNumber(t *testing.T) { - sa := NewSecurityAssociation(nil, 3, 0, 0) + sa := NewSecurityAssociation(nil, 3, 0, 0, 0) seq, _ := sa.GetEndpointsAndNextSequenceNumber(nil) if seq != 0 { @@ -215,7 +215,7 @@ func TestSecurityAssociationGetEndpointsAndNextSequenceNumber(t *testing.T) { t.Fatalf("next sequnce number returned is %d but should be %d", seq, 3) } - sa = NewSecurityAssociation(nil, 3, (^uint32(0)), 0) + sa = NewSecurityAssociation(nil, 3, (^uint32(0)), 0, 0) eps := make([]*net.UDPAddr, 3) for i := range eps { if eps[i] != nil { @@ -244,3 +244,36 @@ func TestSecurityAssociationGetEndpointsAndNextSequenceNumber(t *testing.T) { t.Fatalf("endpoints[2] is %v but should be %v", sa.endpoints[2], addr6) } } + +func TestSecurityAssociationSequenceNumberCheck(t *testing.T) { + sa := NewSecurityAssociation(nil, 1, 0, 23, 10) + if sa.SequenceNumberCheck(0, 0) { + t.Fatal("sequence number 0 from sender 0 shouldn't get accepted") + } + if !sa.SequenceNumberCheck(0, 23) { + t.Fatal("sequence number 23 from sender 0 should get accepted") + } + if !sa.SequenceNumberCheckAndSet(0, 23) { + t.Fatal("sequence number 23 from sender 0 should get accepted") + } + if sa.SequenceNumberCheck(0, 23) { + t.Fatal("sequence number 23 from sender 0 shouldn't get accepted") + } + if !sa.SequenceNumberCheck(42, 23) { + t.Fatal("sequence number 23 from sender 42 should get accepted") + } + if !sa.SequenceNumberCheckAndSet(42, 23) { + t.Fatal("sequence number 23 from sender 42 should get accepted") + } + if sa.SequenceNumberCheck(42, 23) { + t.Fatal("sequence number 23 from sender 42 shouldn't get accepted") + } + if !sa.SequenceNumberCheckAndSet(23, 27) { + t.Fatal("sequence number 27 from sender 23 should get accepted") + } + + sa.seqWindows.Range(func(key, value interface{}) bool { + t.Logf("SeqWin for Sender %v: %v", key, value) + return true + }) +} |