package stun
import (
"crypto/md5"
"crypto/sha1"
"errors"
"fmt"
"strings"
"github.com/pion/stun/internal/hmac"
)
const credentialsSep = ":"
func NewLongTermIntegrity (username , realm , password string ) MessageIntegrity {
k := strings .Join ([]string {username , realm , password }, credentialsSep )
h := md5 .New ()
fmt .Fprint (h , k )
return MessageIntegrity (h .Sum (nil ))
}
func NewShortTermIntegrity (password string ) MessageIntegrity {
return MessageIntegrity (password )
}
type MessageIntegrity []byte
func newHMAC(key , message , buf []byte ) []byte {
mac := hmac .AcquireSHA1 (key )
writeOrPanic (mac , message )
defer hmac .PutSHA1 (mac )
return mac .Sum (buf )
}
func (i MessageIntegrity ) String () string {
return fmt .Sprintf ("KEY: 0x%x" , []byte (i ))
}
const messageIntegritySize = 20
var ErrFingerprintBeforeIntegrity = errors .New ("FINGERPRINT before MESSAGE-INTEGRITY attribute" )
func (i MessageIntegrity ) AddTo (m *Message ) error {
for _ , a := range m .Attributes {
if a .Type == AttrFingerprint {
return ErrFingerprintBeforeIntegrity
}
}
length := m .Length
m .Length += messageIntegritySize + attributeHeaderSize
m .WriteLength ()
v := newHMAC (i , m .Raw , m .Raw [len (m .Raw ):])
m .Length = length
vBuf := make ([]byte , sha1 .Size )
copy (vBuf , v )
m .Add (AttrMessageIntegrity , vBuf )
return nil
}
var ErrIntegrityMismatch = errors .New ("integrity check failed" )
func (i MessageIntegrity ) Check (m *Message ) error {
v , err := m .Get (AttrMessageIntegrity )
if err != nil {
return err
}
var (
length = m .Length
afterIntegrity = false
sizeReduced int
)
for _ , a := range m .Attributes {
if afterIntegrity {
sizeReduced += nearestPaddedValueLength (int (a .Length ))
sizeReduced += attributeHeaderSize
}
if a .Type == AttrMessageIntegrity {
afterIntegrity = true
}
}
m .Length -= uint32 (sizeReduced )
m .WriteLength ()
startOfHMAC := messageHeaderSize + m .Length - (attributeHeaderSize + messageIntegritySize )
b := m .Raw [:startOfHMAC ]
expected := newHMAC (i , b , m .Raw [len (m .Raw ):])
m .Length = length
m .WriteLength ()
return checkHMAC (v , expected )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .