summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2017-11-04 20:02:27 (GMT)
committerChristian Pointner <equinox@anytun.org>2017-11-04 20:02:32 (GMT)
commit3603a67ba4dc8c32c7130848aac7f58115b842ed (patch)
tree098264a9e5239bc90cb3c4523959a164d0882391
parent1fd6cf682d42a318af68c854e8ad4ccf2d8c45d8 (diff)
SA now handles sequence windows
-rw-r--r--satp/security-association.go27
-rw-r--r--satp/security-association_test.go51
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
+ })
+}