package srtp
import (
"encoding/binary"
"fmt"
"github.com/pion/rtcp"
)
const (
maxSRTCPIndex = 0x7FFFFFFF
srtcpHeaderSize = 8
srtcpIndexSize = 4
srtcpEncryptionFlag = 0x80
)
func (c *Context ) decryptRTCP (dst , encrypted []byte ) ([]byte , error ) {
authTagLen , err := c .cipher .AuthTagRTCPLen ()
if err != nil {
return nil , err
}
aeadAuthTagLen , err := c .cipher .AEADAuthTagLen ()
if err != nil {
return nil , err
}
mkiLen := len (c .sendMKI )
if len (encrypted ) < (srtcpHeaderSize + aeadAuthTagLen + srtcpIndexSize + mkiLen + authTagLen ) {
return nil , fmt .Errorf ("%w: %d" , errTooShortRTCP , len (encrypted ))
}
index := c .cipher .getRTCPIndex (encrypted )
ssrc := binary .BigEndian .Uint32 (encrypted [4 :])
s := c .getSRTCPSSRCState (ssrc )
markAsValid , ok := s .replayDetector .Check (uint64 (index ))
if !ok {
return nil , &duplicatedError {Proto : "srtcp" , SSRC : ssrc , Index : index }
}
cipher := c .cipher
if len (c .mkis ) > 0 {
actualMKI := encrypted [len (encrypted )-mkiLen -authTagLen : len (encrypted )-authTagLen ]
cipher , ok = c .mkis [string (actualMKI )]
if !ok {
return nil , ErrMKINotFound
}
}
out , err := cipher .decryptRTCP (dst , encrypted , index , ssrc )
if err != nil {
return nil , err
}
markAsValid ()
return out , nil
}
func (c *Context ) DecryptRTCP (dst , encrypted []byte , header *rtcp .Header ) ([]byte , error ) {
if header == nil {
header = &rtcp .Header {}
}
if err := header .Unmarshal (encrypted ); err != nil {
return nil , err
}
return c .decryptRTCP (dst , encrypted )
}
func (c *Context ) encryptRTCP (dst , decrypted []byte ) ([]byte , error ) {
if len (decrypted ) < srtcpHeaderSize {
return nil , fmt .Errorf ("%w: %d" , errTooShortRTCP , len (decrypted ))
}
ssrc := binary .BigEndian .Uint32 (decrypted [4 :])
ssrcState := c .getSRTCPSSRCState (ssrc )
if ssrcState .srtcpIndex >= maxSRTCPIndex {
return nil , errExceededMaxPackets
}
ssrcState .srtcpIndex ++
return c .cipher .encryptRTCP (dst , decrypted , ssrcState .srtcpIndex , ssrc )
}
func (c *Context ) EncryptRTCP (dst , decrypted []byte , header *rtcp .Header ) ([]byte , error ) {
if header == nil {
header = &rtcp .Header {}
}
if err := header .Unmarshal (decrypted ); err != nil {
return nil , err
}
return c .encryptRTCP (dst , decrypted )
}
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 .