a:integrity: fix case with fingerprint

This commit is contained in:
Aleksandr Razumov
2017-02-21 03:41:26 +03:00
parent 0c49de1e6f
commit d11678fcfd
2 changed files with 33 additions and 9 deletions

View File

@@ -70,12 +70,12 @@ func (i MessageIntegrity) AddTo(m *Message) error {
// The text used as input to HMAC is the STUN message, // The text used as input to HMAC is the STUN message,
// including the header, up to and including the attribute preceding the // including the header, up to and including the attribute preceding the
// MESSAGE-INTEGRITY attribute. // MESSAGE-INTEGRITY attribute.
l := m.Length length := m.Length
// Adjusting m.Length to contain MESSAGE-INTEGRITY TLV. // Adjusting m.Length to contain MESSAGE-INTEGRITY TLV.
m.Length += messageIntegritySize + attributeHeaderSize m.Length += messageIntegritySize + attributeHeaderSize
m.WriteLength() // writing length to m.Raw m.WriteLength() // writing length to m.Raw
v := newHMAC(i, m.Raw) // calculating HMAC for adjusted m.Raw v := newHMAC(i, m.Raw) // calculating HMAC for adjusted m.Raw
m.Length = l // changing m.Length back m.Length = length // changing m.Length back
m.Add(AttrMessageIntegrity, v) m.Add(AttrMessageIntegrity, v)
return nil return nil
} }
@@ -112,9 +112,11 @@ func (i MessageIntegrity) Check(m *Message) error {
// Adjusting length in header to match m.Raw that was // Adjusting length in header to match m.Raw that was
// used when computing HMAC. // used when computing HMAC.
l := m.Length var (
afterIntegrity := false length = m.Length
sizeReduced := int(messageIntegritySize + attributeHeaderSize) afterIntegrity = false
sizeReduced int
)
for _, a := range m.Attributes { for _, a := range m.Attributes {
if afterIntegrity { if afterIntegrity {
sizeReduced += nearestPaddedValueLength(int(a.Length)) sizeReduced += nearestPaddedValueLength(int(a.Length))
@@ -125,8 +127,12 @@ func (i MessageIntegrity) Check(m *Message) error {
} }
} }
m.Length -= uint32(sizeReduced) m.Length -= uint32(sizeReduced)
expected := newHMAC(i, m.Raw[:m.Length+messageHeaderSize]) m.WriteLength()
m.Length = l // startOfHMAC should be first byte of integrity attribute.
startOfHMAC := messageHeaderSize + m.Length - (attributeHeaderSize + messageIntegritySize)
b := m.Raw[:startOfHMAC] // data before integrity attribute
expected := newHMAC(i, b)
m.Length = length
m.WriteLength() // writing length back m.WriteLength() // writing length back
if !hmac.Equal(v, expected) { if !hmac.Equal(v, expected) {
return &IntegrityErr{ return &IntegrityErr{

View File

@@ -24,6 +24,7 @@ func TestMessageIntegrity_AddTo_Simple(t *testing.T) {
if err := i.AddTo(m); err != nil { if err := i.AddTo(m); err != nil {
t.Error(err) t.Error(err)
} }
NewSoftware("software").AddTo(m)
m.WriteHeader() m.WriteHeader()
dM := new(Message) dM := new(Message)
dM.Raw = m.Raw dM.Raw = m.Raw
@@ -33,13 +34,30 @@ func TestMessageIntegrity_AddTo_Simple(t *testing.T) {
if err := i.Check(dM); err != nil { if err := i.Check(dM); err != nil {
t.Error(err) t.Error(err)
} }
m.Raw[3] = m.Raw[3] + 12 // HMAC now invalid dM.Raw[24] += 12 // HMAC now invalid
if err, ok := i.Check(dM).(*IntegrityErr); !ok { if err, ok := i.Check(dM).(*IntegrityErr); !ok {
t.Error(err, "should be *IntegrityErr") t.Error(err, "should be *IntegrityErr")
} }
}) })
} }
func TestMessageIntegrityWithFingerprint(t *testing.T) {
m := new(Message)
m.TransactionID = [transactionIDSize]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
m.WriteHeader()
NewSoftware("software").AddTo(m)
i := NewShortTermIntegrity("pwd")
if err := i.AddTo(m); err != nil {
t.Fatal(err)
}
if err := Fingerprint.AddTo(m); err != nil {
t.Fatal(err)
}
if err := i.Check(m); err != nil {
t.Fatal(err)
}
}
func TestMessageIntegrity(t *testing.T) { func TestMessageIntegrity(t *testing.T) {
m := new(Message) m := new(Message)
//NewSoftware("software") //NewSoftware("software")