New Upstream Snapshot - golang-github-pion-srtp.v2
Ready changes
Summary
Merged new upstream version: 2.0.12+git20230209.1.b173a46 (was: 2.0.9).
Diff
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index f977e74..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-### JetBrains IDE ###
-#####################
-.idea/
-
-### Emacs Temporary Files ###
-#############################
-*~
-
-### Folders ###
-###############
-bin/
-vendor/
-node_modules/
-
-### Files ###
-#############
-*.ivf
-*.ogg
-tags
-cover.out
-*.sw[poe]
-*.wasm
-examples/sfu-ws/cert.pem
-examples/sfu-ws/key.pem
-wasm_exec.js
diff --git a/.golangci.yml b/.golangci.yml
index d7a88ec..48696f1 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -18,7 +18,6 @@ linters:
- bidichk # Checks for dangerous unicode character sequences
- bodyclose # checks whether HTTP response body is closed successfully
- contextcheck # check the function whether use a non-inherited context
- - deadcode # Finds unused code
- decorder # check declaration order and count of types, constants, variables and functions
- depguard # Go linter that checks if package imports are in a list of acceptable packages
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
@@ -60,7 +59,6 @@ linters:
- predeclared # find code that shadows one of Go's predeclared identifiers
- revive # golint replacement, finds style mistakes
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
- - structcheck # Finds unused struct fields
- stylecheck # Stylecheck is a replacement for golint
- tagliatelle # Checks the struct tags.
- tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
@@ -69,7 +67,6 @@ linters:
- unconvert # Remove unnecessary type conversions
- unparam # Reports unused function parameters
- unused # Checks Go code for unused constants, variables, functions and types
- - varcheck # Finds unused global variables and constants
- wastedassign # wastedassign finds wasted assignment statements
- whitespace # Tool for detection of leading and trailing whitespace
disable:
diff --git a/.goreleaser.yml b/.goreleaser.yml
new file mode 100644
index 0000000..2caa5fb
--- /dev/null
+++ b/.goreleaser.yml
@@ -0,0 +1,2 @@
+builds:
+- skip: true
diff --git a/AUTHORS.txt b/AUTHORS.txt
index 2f9cade..2a17730 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -2,7 +2,7 @@
# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
#
# This file is auto generated, using git to list all individuals contributors.
-# see `.github/generate-authors.sh` for the scripting
+# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
adamroach <adam@nostrum.com>
Adrian Cable <adrian.cable@gmail.com>
Agniva De Sarker <agnivade@yahoo.co.in>
@@ -25,3 +25,6 @@ Sean DuBois <sean@siobud.com>
Tobias Fridén <tobias.friden@gmail.com>
Woodrow Douglass <wdouglass@carnegierobotics.com>
Yutaka Takeda <yt0916@gmail.com>
+
+# List of contributors not appearing in Git history
+
diff --git a/context.go b/context.go
index bf871b2..438a51c 100644
--- a/context.go
+++ b/context.go
@@ -3,7 +3,7 @@ package srtp
import (
"fmt"
- "github.com/pion/transport/replaydetector"
+ "github.com/pion/transport/v2/replaydetector"
)
const (
@@ -16,6 +16,7 @@ const (
labelSRTCPSalt = 0x05
maxSequenceNumber = 65535
+ maxROC = (1 << 32) - 1
seqNumMedian = 1 << 15
seqNumMax = 1 << 16
@@ -60,8 +61,7 @@ type Context struct {
// Passing multiple options which set the same parameter let the last one valid.
// Following example create SRTP Context with replay protection with window size of 256.
//
-// decCtx, err := srtp.CreateContext(key, salt, profile, srtp.SRTPReplayProtection(256))
-//
+// decCtx, err := srtp.CreateContext(key, salt, profile, srtp.SRTPReplayProtection(256))
func CreateContext(masterKey, masterSalt []byte, profile ProtectionProfile, opts ...ContextOption) (c *Context, err error) {
keyLen, err := profile.keyLen()
if err != nil {
@@ -112,7 +112,7 @@ func CreateContext(masterKey, masterSalt []byte, profile ProtectionProfile, opts
}
// https://tools.ietf.org/html/rfc3550#appendix-A.1
-func (s *srtpSSRCState) nextRolloverCount(sequenceNumber uint16) (uint32, int32) {
+func (s *srtpSSRCState) nextRolloverCount(sequenceNumber uint16) (roc uint32, diff int32, overflow bool) {
seq := int32(sequenceNumber)
localRoc := uint32(s.index >> 16)
localSeq := int32(s.index & (seqNumMax - 1))
@@ -147,7 +147,7 @@ func (s *srtpSSRCState) nextRolloverCount(sequenceNumber uint16) (uint32, int32)
}
}
- return guessRoc, difference
+ return guessRoc, difference, (guessRoc == 0 && localRoc == maxROC)
}
func (s *srtpSSRCState) updateRolloverCount(sequenceNumber uint16, difference int32) {
@@ -201,7 +201,8 @@ func (c *Context) ROC(ssrc uint32) (uint32, bool) {
// SetROC sets SRTP rollover counter value of specified SSRC.
func (c *Context) SetROC(ssrc uint32, roc uint32) {
s := c.getSRTPSSRCState(ssrc)
- s.index = uint64(roc<<16) | (s.index & (seqNumMax - 1))
+ s.index = uint64(roc) << 16
+ s.rolloverHasProcessed = false
}
// Index returns SRTCP index value of specified SSRC.
diff --git a/crypto.go b/crypto.go
index e2eb9b2..0625e91 100644
--- a/crypto.go
+++ b/crypto.go
@@ -2,25 +2,9 @@ package srtp
import (
"crypto/cipher"
-)
-
-// xorBytes computes the exclusive-or of src1 and src2 and stores it in dst.
-// It returns the number of bytes written.
-func xorBytes(dst, src1, src2 []byte) int {
- n := len(src1)
- if len(src2) < n {
- n = len(src2)
- }
- if len(dst) < n {
- n = len(dst)
- }
- for i := 0; i < n; i++ {
- dst[i] = src1[i] ^ src2[i]
- }
-
- return n
-}
+ "github.com/pion/transport/v2/utils/xor"
+)
// incrementCTR increments a big-endian integer of arbitrary size.
func incrementCTR(ctr []byte) {
@@ -48,7 +32,7 @@ func xorBytesCTR(block cipher.Block, iv []byte, dst, src []byte) error {
for i < len(src) {
block.Encrypt(stream, ctr)
incrementCTR(ctr)
- n := xorBytes(dst[i:], src[i:], stream)
+ n := xor.XorBytes(dst[i:], src[i:], stream)
if n == 0 {
break
}
diff --git a/crypto_test.go b/crypto_test.go
index 4a5bf8f..fe98e0f 100644
--- a/crypto_test.go
+++ b/crypto_test.go
@@ -62,22 +62,3 @@ func TestXorBytesCTRInvalidIvLength(t *testing.T) {
test(make([]byte, block.BlockSize()-1))
test(make([]byte, block.BlockSize()+1))
}
-
-func TestXorBytesBufferSize(t *testing.T) {
- a := []byte{3}
- b := []byte{5, 6}
- dst := make([]byte, 3)
-
- xorBytes(dst, a, b)
- require.Equal(t, dst, []byte{6, 0, 0})
-
- xorBytes(dst, b, a)
- require.Equal(t, dst, []byte{6, 0, 0})
-
- a = []byte{1, 1, 1, 1}
- b = []byte{2, 2, 2, 2}
- dst = make([]byte, 3)
-
- xorBytes(dst, a, b)
- require.Equal(t, dst, []byte{3, 3, 3})
-}
diff --git a/debian/changelog b/debian/changelog
index fd25483..d5590eb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-pion-srtp.v2 (2.0.12+git20230209.1.b173a46-1) UNRELEASED; urgency=low
+
+ * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk> Thu, 09 Feb 2023 18:55:29 -0000
+
golang-github-pion-srtp.v2 (2.0.9-2) unstable; urgency=medium
* Source-only upload.
diff --git a/errors.go b/errors.go
index 55a67bc..db5b7db 100644
--- a/errors.go
+++ b/errors.go
@@ -19,6 +19,7 @@ var (
errPayloadDiffers = errors.New("payload differs")
errStartedChannelUsedIncorrectly = errors.New("started channel used incorrectly, should only be closed")
errBadIVLength = errors.New("bad iv length in xorBytesCTR")
+ errExceededMaxPackets = errors.New("exceeded the maximum number of packets")
errStreamNotInited = errors.New("stream has not been inited, unable to close")
errStreamAlreadyClosed = errors.New("stream is already closed")
diff --git a/go.mod b/go.mod
index 9f0e9a6..223d2d3 100644
--- a/go.mod
+++ b/go.mod
@@ -4,8 +4,8 @@ go 1.14
require (
github.com/pion/logging v0.2.2
- github.com/pion/rtcp v1.2.9
+ github.com/pion/rtcp v1.2.10
github.com/pion/rtp v1.7.13
- github.com/pion/transport v0.13.0
- github.com/stretchr/testify v1.7.1
+ github.com/pion/transport/v2 v2.0.1
+ github.com/stretchr/testify v1.8.1
)
diff --git a/go.sum b/go.sum
index 4b2d50e..9ab67ed 100644
--- a/go.sum
+++ b/go.sum
@@ -1,29 +1,56 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
-github.com/pion/rtcp v1.2.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U=
-github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
+github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
+github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
-github.com/pion/transport v0.13.0 h1:KWTA5ZrQogizzYwPEciGtHPLwpAjE91FgXnyu+Hv2uY=
-github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
+github.com/pion/transport/v2 v2.0.1 h1:cbSk3gzoSBEIKVGNYeghXQSp47s1H9ttoP5JyLCgxLE=
+github.com/pion/transport/v2 v2.0.1/go.mod h1:93OYg91+mrGxKW+Jrgzmqr80kgXqD7J0yybOrdr7w0Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c h1:WtYZ93XtWSO5KlOMgPZu7hXY9WhMZpprvlm5VwvAl8c=
-golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/option.go b/option.go
index 86ecd8e..84df19c 100644
--- a/option.go
+++ b/option.go
@@ -1,7 +1,7 @@
package srtp
import (
- "github.com/pion/transport/replaydetector"
+ "github.com/pion/transport/v2/replaydetector"
)
// ContextOption represents option of Context using the functional options pattern.
@@ -11,7 +11,7 @@ type ContextOption func(*Context) error
func SRTPReplayProtection(windowSize uint) ContextOption { // nolint:revive
return func(c *Context) error {
c.newSRTPReplayDetector = func() replaydetector.ReplayDetector {
- return replaydetector.WithWrap(windowSize, maxSequenceNumber)
+ return replaydetector.New(windowSize, maxROC<<16|maxSequenceNumber)
}
return nil
}
@@ -21,7 +21,7 @@ func SRTPReplayProtection(windowSize uint) ContextOption { // nolint:revive
func SRTCPReplayProtection(windowSize uint) ContextOption {
return func(c *Context) error {
c.newSRTCPReplayDetector = func() replaydetector.ReplayDetector {
- return replaydetector.WithWrap(windowSize, maxSRTCPIndex)
+ return replaydetector.New(windowSize, maxSRTCPIndex)
}
return nil
}
diff --git a/renovate.json b/renovate.json
index f161405..f1bb98c 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,27 +1,6 @@
{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
- "config:base",
- ":disableDependencyDashboard"
- ],
- "postUpdateOptions": [
- "gomodTidy"
- ],
- "commitBody": "Generated by renovateBot",
- "packageRules": [
- {
- "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
- "automerge": true
- },
- {
- "packagePatterns": ["^golang.org/x/"],
- "schedule": ["on the first day of the month"]
- }
- ],
- "ignorePaths": [
- ".github/workflows/generate-authors.yml",
- ".github/workflows/lint.yaml",
- ".github/workflows/renovate-go-mod-fix.yaml",
- ".github/workflows/test.yaml",
- ".github/workflows/tidy-check.yaml"
+ "github>pion/renovate-config"
]
}
diff --git a/session.go b/session.go
index 8148aff..f72dcda 100644
--- a/session.go
+++ b/session.go
@@ -7,7 +7,7 @@ import (
"sync"
"github.com/pion/logging"
- "github.com/pion/transport/packetio"
+ "github.com/pion/transport/v2/packetio"
)
type streamSession interface {
diff --git a/session_srtcp_test.go b/session_srtcp_test.go
index b2043d7..4314011 100644
--- a/session_srtcp_test.go
+++ b/session_srtcp_test.go
@@ -12,7 +12,7 @@ import (
"time"
"github.com/pion/rtcp"
- "github.com/pion/transport/test"
+ "github.com/pion/transport/v2/test"
)
const rtcpHeaderSize = 4
diff --git a/session_srtp_test.go b/session_srtp_test.go
index a3798ba..1143c50 100644
--- a/session_srtp_test.go
+++ b/session_srtp_test.go
@@ -11,7 +11,7 @@ import (
"time"
"github.com/pion/rtp"
- "github.com/pion/transport/test"
+ "github.com/pion/transport/v2/test"
)
func TestSessionSRTPBadInit(t *testing.T) {
diff --git a/srtcp.go b/srtcp.go
index d3e387b..2812851 100644
--- a/srtcp.go
+++ b/srtcp.go
@@ -63,11 +63,16 @@ func (c *Context) encryptRTCP(dst, decrypted []byte) ([]byte, error) {
ssrc := binary.BigEndian.Uint32(decrypted[4:])
s := c.getSRTCPSSRCState(ssrc)
+ if s.srtcpIndex >= maxSRTCPIndex {
+ // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key
+ // (whichever occurs before), the key management MUST be called to provide new master key(s)
+ // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated.
+ // https://www.rfc-editor.org/rfc/rfc3711#section-9.2
+ return nil, errExceededMaxPackets
+ }
+
// We roll over early because MSB is used for marking as encrypted
s.srtcpIndex++
- if s.srtcpIndex > maxSRTCPIndex {
- s.srtcpIndex = 0
- }
return c.cipher.encryptRTCP(dst, decrypted, s.srtcpIndex, ssrc)
}
diff --git a/srtcp_test.go b/srtcp_test.go
index f2e870d..96133ab 100644
--- a/srtcp_test.go
+++ b/srtcp_test.go
@@ -25,7 +25,7 @@ type rtcpTestCase struct {
packets []rtcpTestPacket
}
-func rtcpTestCasesSingle() map[string]rtcpTestCase {
+func rtcpTestCases() map[string]rtcpTestCase {
return map[string]rtcpTestCase{
"AEAD_AES_128_GCM": {
algo: ProtectionProfileAeadAes128Gcm,
@@ -112,72 +112,6 @@ func rtcpTestCasesSingle() map[string]rtcpTestCase {
}
}
-func rtcpTestCases() map[string]rtcpTestCase {
- single := rtcpTestCasesSingle()
- return map[string]rtcpTestCase{
- "AEAD_AES_128_GCM": single["AEAD_AES_128_GCM"],
- "AES_128_CM_HMAC_SHA1_80": {
- algo: ProtectionProfileAes128CmHmacSha1_80,
- masterKey: single["AES_128_CM_HMAC_SHA1_80"].masterKey,
- masterSalt: single["AES_128_CM_HMAC_SHA1_80"].masterSalt,
- packets: []rtcpTestPacket{
- single["AES_128_CM_HMAC_SHA1_80"].packets[0],
- single["AES_128_CM_HMAC_SHA1_80"].packets[1],
- {
- ssrc: 0x11111111,
- index: 0x7ffffffe, // Upper boundary of index
- pktType: rtcp.TypeSenderReport,
- encrypted: []byte{
- 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
- 0x17, 0x8c, 0x15, 0xf1, 0x4b, 0x11, 0xda, 0xf5,
- 0x74, 0x53, 0x86, 0x2b, 0xc9, 0x07, 0x29, 0x40,
- 0xbf, 0x22, 0xf6, 0x46, 0x11, 0xa4, 0xc1, 0x3a,
- 0xff, 0x5a, 0xbd, 0xd0, 0xf8, 0x8b, 0x38, 0xe4,
- 0x95, 0x38, 0x5d, 0xcf, 0x1b, 0xf5, 0x27, 0x77,
- 0xfb, 0xdb, 0x3f, 0x10, 0x68, 0x99, 0xd8, 0xad,
- 0xff, 0xff, 0xff, 0xff, 0x5a, 0x99, 0xce, 0xed,
- 0x9f, 0x2e, 0x4d, 0x9d, 0xfa, 0x97,
- },
- decrypted: []byte{
- 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
- 0x04, 0x99, 0x47, 0x53, 0xc4, 0x1e, 0xb9, 0xde,
- 0x52, 0xa3, 0x1d, 0x77, 0x2f, 0xff, 0xcc, 0x75,
- 0xbb, 0x6a, 0x29, 0xb8, 0x01, 0xb7, 0x2e, 0x4b,
- 0x4e, 0xcb, 0xa4, 0x81, 0x2d, 0x46, 0x04, 0x5e,
- 0x86, 0x90, 0x17, 0x4f, 0x4d, 0x78, 0x2f, 0x58,
- 0xb8, 0x67, 0x91, 0x89, 0xe3, 0x61, 0x01, 0x7d,
- },
- },
- {
- ssrc: 0x11111111,
- index: 0x7fffffff, // Will be wrapped to 0
- pktType: rtcp.TypeSenderReport,
- encrypted: []byte{
- 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
- 0x17, 0x8c, 0x15, 0xf1, 0x4b, 0x11, 0xda, 0xf5,
- 0x74, 0x53, 0x86, 0x2b, 0xc9, 0x07, 0x29, 0x40,
- 0xbf, 0x22, 0xf6, 0x46, 0x11, 0xa4, 0xc1, 0x3a,
- 0xff, 0x5a, 0xbd, 0xd0, 0xf8, 0x8b, 0x38, 0xe4,
- 0x95, 0x38, 0x5d, 0xcf, 0x1b, 0xf5, 0x27, 0x77,
- 0xfb, 0xdb, 0x3f, 0x10, 0x68, 0x99, 0xd8, 0xad,
- 0x80, 0x00, 0x00, 0x00, 0x7d, 0x51, 0xf8, 0x0e,
- 0x56, 0x40, 0x72, 0x7b, 0x9e, 0x02,
- },
- decrypted: []byte{
- 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
- 0xda, 0xb5, 0xe0, 0x56, 0x9a, 0x4a, 0x74, 0xed,
- 0x8a, 0x54, 0x0c, 0xcf, 0xd5, 0x09, 0xb1, 0x40,
- 0x01, 0x42, 0xc3, 0x9a, 0x76, 0x00, 0xa9, 0xd4,
- 0xf7, 0x29, 0x9e, 0x51, 0xfb, 0x3c, 0xc1, 0x74,
- 0x72, 0xf9, 0x52, 0xb1, 0x92, 0x31, 0xca, 0x22,
- 0xab, 0x3e, 0xc5, 0x5f, 0x83, 0x34, 0xf0, 0x28,
- },
- },
- },
- },
- }
-}
-
func TestRTCPLifecycle(t *testing.T) {
options := map[string][]ContextOption{
"Default": {},
@@ -371,7 +305,7 @@ func TestRTCPInvalidAuthTag(t *testing.T) {
}
func TestRTCPReplayDetectorSeparation(t *testing.T) {
- for caseName, testCase := range rtcpTestCasesSingle() {
+ for caseName, testCase := range rtcpTestCases() {
testCase := testCase
t.Run(caseName, func(t *testing.T) {
assert := assert.New(t)
@@ -409,7 +343,7 @@ func getRTCPIndex(encrypted []byte, authTagLen int) uint32 {
}
func TestEncryptRTCPSeparation(t *testing.T) {
- for caseName, testCase := range rtcpTestCasesSingle() {
+ for caseName, testCase := range rtcpTestCases() {
testCase := testCase
t.Run(caseName, func(t *testing.T) {
assert := assert.New(t)
@@ -462,7 +396,7 @@ func TestEncryptRTCPSeparation(t *testing.T) {
}
func TestRTCPDecryptShortenedPacket(t *testing.T) {
- for caseName, testCase := range rtcpTestCasesSingle() {
+ for caseName, testCase := range rtcpTestCases() {
testCase := testCase
t.Run(caseName, func(t *testing.T) {
pkt := testCase.packets[0]
@@ -479,3 +413,157 @@ func TestRTCPDecryptShortenedPacket(t *testing.T) {
})
}
}
+
+func TestRTCPMaxPackets(t *testing.T) {
+ const ssrc = 0x11111111
+ testCases := map[string]rtcpTestCase{
+ "AEAD_AES_128_GCM": {
+ algo: ProtectionProfileAeadAes128Gcm,
+ masterKey: []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
+ masterSalt: []byte{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab},
+ packets: []rtcpTestPacket{
+ {
+ pktType: rtcp.TypeSenderReport,
+ encrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x02, 0xb6, 0xc1, 0x47, 0x92, 0xbe, 0xf0, 0xae,
+ 0xd9, 0x40, 0xa5, 0x1c, 0xbe, 0xec, 0xaf, 0xfc,
+ 0x7d, 0x86, 0x3b, 0xbb, 0x93, 0x0c, 0xb0, 0xd4,
+ 0xea, 0x4a, 0x3c, 0x5b, 0xd1, 0xd5, 0x47, 0xb1,
+ 0x1a, 0x61, 0xae, 0xa6, 0x1a, 0x0c, 0xb9, 0x14,
+ 0xa5, 0x16, 0x08, 0xe4, 0xfb, 0x0d, 0x15, 0xba,
+ 0x7f, 0x70, 0x2b, 0xb8, 0x99, 0x97, 0x91, 0xfd,
+ 0x53, 0x03, 0xcd, 0x57, 0xbb, 0x8f, 0x93, 0xbe,
+ 0xff, 0xff, 0xff, 0xff,
+ },
+ decrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x04, 0x99, 0x47, 0x53, 0xc4, 0x1e, 0xb9, 0xde,
+ 0x52, 0xa3, 0x1d, 0x77, 0x2f, 0xff, 0xcc, 0x75,
+ 0xbb, 0x6a, 0x29, 0xb8, 0x01, 0xb7, 0x2e, 0x4b,
+ 0x4e, 0xcb, 0xa4, 0x81, 0x2d, 0x46, 0x04, 0x5e,
+ 0x86, 0x90, 0x17, 0x4f, 0x4d, 0x78, 0x2f, 0x58,
+ 0xb8, 0x67, 0x91, 0x89, 0xe3, 0x61, 0x01, 0x7d,
+ },
+ },
+ {
+ pktType: rtcp.TypeSenderReport,
+ encrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x77, 0x47, 0x0c, 0x21, 0xc2, 0xcd, 0x33, 0xa7,
+ 0x5a, 0x81, 0xb5, 0xb5, 0x8f, 0xe2, 0x34, 0x28,
+ 0x11, 0xa8, 0xa3, 0x34, 0xf8, 0x9d, 0xfc, 0xd8,
+ 0xcb, 0x87, 0xe2, 0x51, 0x8e, 0xae, 0xdb, 0xfd,
+ 0x9d, 0xf1, 0xfa, 0x18, 0xe2, 0xdc, 0x0a, 0xd4,
+ 0xe3, 0x06, 0x18, 0xff, 0xf7, 0x27, 0x92, 0x1f,
+ 0x28, 0xcd, 0x3c, 0xf8, 0xa4, 0x0a, 0x2b, 0xbb,
+ 0x5b, 0x1f, 0x4d, 0x1f, 0xef, 0x0e, 0xc4, 0x91,
+ 0x80, 0x00, 0x00, 0x01,
+ },
+ decrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0xda, 0xb5, 0xe0, 0x56, 0x9a, 0x4a, 0x74, 0xed,
+ 0x8a, 0x54, 0x0c, 0xcf, 0xd5, 0x09, 0xb1, 0x40,
+ 0x01, 0x42, 0xc3, 0x9a, 0x76, 0x00, 0xa9, 0xd4,
+ 0xf7, 0x29, 0x9e, 0x51, 0xfb, 0x3c, 0xc1, 0x74,
+ 0x72, 0xf9, 0x52, 0xb1, 0x92, 0x31, 0xca, 0x22,
+ 0xab, 0x3e, 0xc5, 0x5f, 0x83, 0x34, 0xf0, 0x28,
+ },
+ },
+ },
+ },
+ "AES_128_CM_HMAC_SHA1_80": {
+ algo: ProtectionProfileAes128CmHmacSha1_80,
+ masterKey: []byte{0xfd, 0xa6, 0x25, 0x95, 0xd7, 0xf6, 0x92, 0x6f, 0x7d, 0x9c, 0x02, 0x4c, 0xc9, 0x20, 0x9f, 0x34},
+ masterSalt: []byte{0xa9, 0x65, 0x19, 0x85, 0x54, 0x0b, 0x47, 0xbe, 0x2f, 0x27, 0xa8, 0xb8, 0x81, 0x23},
+ packets: []rtcpTestPacket{
+ {
+ encrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x17, 0x8c, 0x15, 0xf1, 0x4b, 0x11, 0xda, 0xf5,
+ 0x74, 0x53, 0x86, 0x2b, 0xc9, 0x07, 0x29, 0x40,
+ 0xbf, 0x22, 0xf6, 0x46, 0x11, 0xa4, 0xc1, 0x3a,
+ 0xff, 0x5a, 0xbd, 0xd0, 0xf8, 0x8b, 0x38, 0xe4,
+ 0x95, 0x38, 0x5d, 0xcf, 0x1b, 0xf5, 0x27, 0x77,
+ 0xfb, 0xdb, 0x3f, 0x10, 0x68, 0x99, 0xd8, 0xad,
+ 0xff, 0xff, 0xff, 0xff, 0x5a, 0x99, 0xce, 0xed,
+ 0x9f, 0x2e, 0x4d, 0x9d, 0xfa, 0x97,
+ },
+ decrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x04, 0x99, 0x47, 0x53, 0xc4, 0x1e, 0xb9, 0xde,
+ 0x52, 0xa3, 0x1d, 0x77, 0x2f, 0xff, 0xcc, 0x75,
+ 0xbb, 0x6a, 0x29, 0xb8, 0x01, 0xb7, 0x2e, 0x4b,
+ 0x4e, 0xcb, 0xa4, 0x81, 0x2d, 0x46, 0x04, 0x5e,
+ 0x86, 0x90, 0x17, 0x4f, 0x4d, 0x78, 0x2f, 0x58,
+ 0xb8, 0x67, 0x91, 0x89, 0xe3, 0x61, 0x01, 0x7d,
+ },
+ },
+ {
+ encrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0x12, 0x71, 0x75, 0x7a, 0xb0, 0xfd, 0x80, 0xcb,
+ 0x26, 0xbb, 0x54, 0x5a, 0x1c, 0x0e, 0x98, 0x09,
+ 0xbe, 0x60, 0x23, 0xd8, 0xe6, 0x6e, 0x68, 0xe8,
+ 0x6e, 0x9c, 0xb2, 0x7e, 0x02, 0xa7, 0xab, 0xfe,
+ 0xb3, 0xf4, 0x4c, 0x13, 0xc3, 0xac, 0x97, 0x2c,
+ 0x35, 0x91, 0xbb, 0x37, 0x9c, 0x86, 0x28, 0x85,
+ 0x80, 0x00, 0x00, 0x01, 0x89, 0x76, 0x07, 0xca,
+ 0xd9, 0xc4, 0xcb, 0xca, 0x66, 0xab,
+ },
+ decrypted: []byte{
+ 0x80, 0xc8, 0x00, 0x06, 0x11, 0x11, 0x11, 0x11,
+ 0xda, 0xb5, 0xe0, 0x56, 0x9a, 0x4a, 0x74, 0xed,
+ 0x8a, 0x54, 0x0c, 0xcf, 0xd5, 0x09, 0xb1, 0x40,
+ 0x01, 0x42, 0xc3, 0x9a, 0x76, 0x00, 0xa9, 0xd4,
+ 0xf7, 0x29, 0x9e, 0x51, 0xfb, 0x3c, 0xc1, 0x74,
+ 0x72, 0xf9, 0x52, 0xb1, 0x92, 0x31, 0xca, 0x22,
+ 0xab, 0x3e, 0xc5, 0x5f, 0x83, 0x34, 0xf0, 0x28,
+ },
+ },
+ },
+ },
+ }
+
+ for caseName, testCase := range testCases {
+ testCase := testCase
+ t.Run(caseName, func(t *testing.T) {
+ assert := assert.New(t)
+ encryptContext, err := CreateContext(testCase.masterKey, testCase.masterSalt, testCase.algo)
+ if err != nil {
+ t.Errorf("CreateContext failed: %v", err)
+ }
+
+ decryptContext, err := CreateContext(testCase.masterKey, testCase.masterSalt, testCase.algo, SRTCPReplayProtection(10))
+ if err != nil {
+ t.Errorf("CreateContext failed: %v", err)
+ }
+
+ // Upper boundary of index
+ encryptContext.SetIndex(ssrc, 0x7ffffffe)
+
+ decryptResult, err := decryptContext.DecryptRTCP(nil, testCase.packets[0].encrypted, nil)
+ if err != nil {
+ t.Error(err)
+ }
+ assert.Equal(testCase.packets[0].decrypted, decryptResult, "RTCP failed to decrypt")
+
+ encryptResult, err := encryptContext.EncryptRTCP(nil, testCase.packets[0].decrypted, nil)
+ if err != nil {
+ t.Error(err)
+ }
+ assert.Equal(testCase.packets[0].encrypted, encryptResult, "RTCP failed to encrypt")
+
+ // Next packet will exceeds the maximum packet count
+ _, err = decryptContext.DecryptRTCP(nil, testCase.packets[1].encrypted, nil)
+ if !errors.Is(err, errDuplicated) {
+ t.Errorf("Expected error: '%v', got: '%v'", errDuplicated, err)
+ }
+
+ _, err = encryptContext.EncryptRTCP(nil, testCase.packets[1].decrypted, nil)
+ if !errors.Is(err, errExceededMaxPackets) {
+ t.Errorf("Expected error: '%v', got: '%v'", errExceededMaxPackets, err)
+ }
+ })
+ }
+}
diff --git a/srtp.go b/srtp.go
index 0feaf0f..c8ad8a5 100644
--- a/srtp.go
+++ b/srtp.go
@@ -8,7 +8,10 @@ import (
func (c *Context) decryptRTP(dst, ciphertext []byte, header *rtp.Header, headerLen int) ([]byte, error) {
s := c.getSRTPSSRCState(header.SSRC)
- markAsValid, ok := s.replayDetector.Check(uint64(header.SequenceNumber))
+ roc, diff, _ := s.nextRolloverCount(header.SequenceNumber)
+ markAsValid, ok := s.replayDetector.Check(
+ (uint64(roc) << 16) | uint64(header.SequenceNumber),
+ )
if !ok {
return nil, &duplicatedError{
Proto: "srtp", SSRC: header.SSRC, Index: uint32(header.SequenceNumber),
@@ -20,7 +23,6 @@ func (c *Context) decryptRTP(dst, ciphertext []byte, header *rtp.Header, headerL
return nil, err
}
dst = growBufferSize(dst, len(ciphertext)-authTagLen)
- roc, diff := s.nextRolloverCount(header.SequenceNumber)
dst, err = c.cipher.decryptRTP(dst, ciphertext, header, headerLen, roc)
if err != nil {
@@ -67,7 +69,14 @@ func (c *Context) EncryptRTP(dst []byte, plaintext []byte, header *rtp.Header) (
// Similar to above but faster because it can avoid unmarshaling the header and marshaling the payload.
func (c *Context) encryptRTP(dst []byte, header *rtp.Header, payload []byte) (ciphertext []byte, err error) {
s := c.getSRTPSSRCState(header.SSRC)
- roc, diff := s.nextRolloverCount(header.SequenceNumber)
+ roc, diff, ovf := s.nextRolloverCount(header.SequenceNumber)
+ if ovf {
+ // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key
+ // (whichever occurs before), the key management MUST be called to provide new master key(s)
+ // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated.
+ // https://www.rfc-editor.org/rfc/rfc3711#section-9.2
+ return nil, errExceededMaxPackets
+ }
s.updateRolloverCount(header.SequenceNumber, diff)
return c.cipher.encryptRTP(dst, header, payload, roc)
diff --git a/srtp_test.go b/srtp_test.go
index 8333b48..e239614 100644
--- a/srtp_test.go
+++ b/srtp_test.go
@@ -76,68 +76,104 @@ func TestRolloverCount(t *testing.T) {
s := &srtpSSRCState{ssrc: defaultSsrc}
// Set initial seqnum
- roc, diff := s.nextRolloverCount(65530)
+ roc, diff, ovf := s.nextRolloverCount(65530)
if roc != 0 {
t.Errorf("Initial rolloverCounter must be 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(65530, diff)
// Invalid packets never update ROC
- _, _ = s.nextRolloverCount(0)
- _, _ = s.nextRolloverCount(0x4000)
- _, _ = s.nextRolloverCount(0x8000)
- _, _ = s.nextRolloverCount(0xFFFF)
- _, _ = s.nextRolloverCount(0)
+ s.nextRolloverCount(0)
+ s.nextRolloverCount(0x4000)
+ s.nextRolloverCount(0x8000)
+ s.nextRolloverCount(0xFFFF)
+ s.nextRolloverCount(0)
// We rolled over to 0
- roc, diff = s.nextRolloverCount(0)
+ roc, diff, ovf = s.nextRolloverCount(0)
if roc != 1 {
t.Errorf("rolloverCounter was not updated after it crossed 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(0, diff)
- roc, diff = s.nextRolloverCount(65530)
+ roc, diff, ovf = s.nextRolloverCount(65530)
if roc != 0 {
t.Errorf("rolloverCounter was not updated when it rolled back, failed to handle out of order")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(65530, diff)
- roc, diff = s.nextRolloverCount(5)
+ roc, diff, ovf = s.nextRolloverCount(5)
if roc != 1 {
t.Errorf("rolloverCounter was not updated when it rolled over initial, to handle out of order")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(5, diff)
- _, diff = s.nextRolloverCount(6)
+ _, diff, _ = s.nextRolloverCount(6)
s.updateRolloverCount(6, diff)
- _, diff = s.nextRolloverCount(7)
+ _, diff, _ = s.nextRolloverCount(7)
s.updateRolloverCount(7, diff)
- roc, diff = s.nextRolloverCount(8)
+ roc, diff, _ = s.nextRolloverCount(8)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
s.updateRolloverCount(8, diff)
// valid packets never update ROC
- roc, diff = s.nextRolloverCount(0x4000)
+ roc, diff, ovf = s.nextRolloverCount(0x4000)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(0x4000, diff)
- roc, diff = s.nextRolloverCount(0x8000)
+ roc, diff, ovf = s.nextRolloverCount(0x8000)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(0x8000, diff)
- roc, diff = s.nextRolloverCount(0xFFFF)
+ roc, diff, ovf = s.nextRolloverCount(0xFFFF)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(0xFFFF, diff)
- roc, _ = s.nextRolloverCount(0)
+ roc, _, ovf = s.nextRolloverCount(0)
if roc != 2 {
t.Errorf("rolloverCounter must be incremented after wrapping, got %d", roc)
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
+}
+
+func TestRolloverCountOverflow(t *testing.T) {
+ s := &srtpSSRCState{
+ ssrc: defaultSsrc,
+ index: maxROC << 16,
+ }
+ s.updateRolloverCount(0xFFFF, 0)
+ _, _, ovf := s.nextRolloverCount(0)
+ if !ovf {
+ t.Error("Should overflow")
+ }
}
func buildTestContext(profile ProtectionProfile, opts ...ContextOption) (*Context, error) {
@@ -541,57 +577,87 @@ func BenchmarkDecryptRTP(b *testing.B) {
func TestRolloverCount2(t *testing.T) {
s := &srtpSSRCState{ssrc: defaultSsrc}
- roc, diff := s.nextRolloverCount(30123)
+ roc, diff, ovf := s.nextRolloverCount(30123)
if roc != 0 {
t.Errorf("Initial rolloverCounter must be 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(30123, diff)
- roc, diff = s.nextRolloverCount(62892) // 30123 + (1 << 15) + 1
+ roc, diff, ovf = s.nextRolloverCount(62892) // 30123 + (1 << 15) + 1
if roc != 0 {
t.Errorf("Initial rolloverCounter must be 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(62892, diff)
- roc, diff = s.nextRolloverCount(204)
+ roc, diff, ovf = s.nextRolloverCount(204)
if roc != 1 {
t.Errorf("rolloverCounter was not updated after it crossed 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(62892, diff)
- roc, diff = s.nextRolloverCount(64535)
+ roc, diff, ovf = s.nextRolloverCount(64535)
if roc != 0 {
t.Errorf("rolloverCounter was not updated when it rolled back, failed to handle out of order")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(64535, diff)
- roc, diff = s.nextRolloverCount(205)
+ roc, diff, ovf = s.nextRolloverCount(205)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(205, diff)
- roc, diff = s.nextRolloverCount(1)
+ roc, diff, ovf = s.nextRolloverCount(1)
if roc != 1 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(1, diff)
- roc, diff = s.nextRolloverCount(64532)
+ roc, diff, ovf = s.nextRolloverCount(64532)
if roc != 0 {
t.Errorf("rolloverCounter was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(64532, diff)
- roc, diff = s.nextRolloverCount(65534)
+ roc, diff, ovf = s.nextRolloverCount(65534)
if roc != 0 {
t.Errorf("index was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(65534, diff)
- roc, diff = s.nextRolloverCount(64532)
+ roc, diff, ovf = s.nextRolloverCount(64532)
if roc != 0 {
t.Errorf("index was improperly updated for non-significant packets")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(65532, diff)
- roc, diff = s.nextRolloverCount(205)
+ roc, diff, ovf = s.nextRolloverCount(205)
if roc != 1 {
t.Errorf("index was not updated after it crossed 0")
}
+ if ovf {
+ t.Error("Should not overflow")
+ }
s.updateRolloverCount(65532, diff)
}
@@ -660,3 +726,126 @@ func TestRTPDecryptShotenedPacket(t *testing.T) {
})
}
}
+
+func TestRTPMaxPackets(t *testing.T) {
+ profiles := map[string]ProtectionProfile{
+ "CTR": profileCTR,
+ "GCM": profileGCM,
+ }
+ for name, profile := range profiles {
+ profile := profile
+ t.Run(name, func(t *testing.T) {
+ context, err := buildTestContext(profile)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ context.SetROC(1, (1<<32)-1)
+
+ pkt0 := &rtp.Packet{
+ Header: rtp.Header{
+ SSRC: 1,
+ SequenceNumber: 0xffff,
+ },
+ Payload: []byte{0, 1},
+ }
+ raw0, err0 := pkt0.Marshal()
+ if err0 != nil {
+ t.Fatal(err0)
+ }
+ if _, errEnc := context.EncryptRTP(nil, raw0, nil); errEnc != nil {
+ t.Fatal(errEnc)
+ }
+
+ pkt1 := &rtp.Packet{
+ Header: rtp.Header{
+ SSRC: 1,
+ SequenceNumber: 0x0,
+ },
+ Payload: []byte{0, 1},
+ }
+ raw1, err1 := pkt1.Marshal()
+ if err1 != nil {
+ t.Fatal(err1)
+ }
+ if _, errEnc := context.EncryptRTP(nil, raw1, nil); !errors.Is(errEnc, errExceededMaxPackets) {
+ t.Fatalf("Expected error '%v', got '%v'", errExceededMaxPackets, errEnc)
+ }
+ })
+ }
+}
+
+func TestRTPBurstLossWithSetROC(t *testing.T) {
+ profiles := map[string]ProtectionProfile{
+ "CTR": profileCTR,
+ "GCM": profileGCM,
+ }
+ for name, profile := range profiles {
+ profile := profile
+ t.Run(name, func(t *testing.T) {
+ assert := assert.New(t)
+
+ encryptContext, err := buildTestContext(profile)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ type packetWithROC struct {
+ pkt rtp.Packet
+ enc []byte
+ raw []byte
+
+ roc uint32
+ }
+
+ var pkts []*packetWithROC
+ encryptContext.SetROC(1, 3)
+ for i := 0x8C00; i < 0x20400; i += 0x100 {
+ p := &packetWithROC{
+ pkt: rtp.Packet{
+ Payload: []byte{
+ byte(i >> 16),
+ byte(i >> 8),
+ byte(i),
+ },
+ Header: rtp.Header{
+ Marker: true,
+ SSRC: 1,
+ SequenceNumber: uint16(i),
+ },
+ },
+ }
+ b, errMarshal := p.pkt.Marshal()
+ if errMarshal != nil {
+ t.Fatal(errMarshal)
+ }
+ p.raw = b
+ enc, errEnc := encryptContext.EncryptRTP(nil, b, nil)
+ if errEnc != nil {
+ t.Fatal(errEnc)
+ }
+ p.roc, _ = encryptContext.ROC(1)
+ if 0x9000 < i && i < 0x20100 {
+ continue
+ }
+ p.enc = enc
+ pkts = append(pkts, p)
+ }
+
+ decryptContext, err := buildTestContext(profile)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, p := range pkts {
+ decryptContext.SetROC(1, p.roc)
+ pkt, err := decryptContext.DecryptRTP(nil, p.enc, nil)
+ if err != nil {
+ t.Errorf("roc=%d, seq=%d: %v", p.roc, p.pkt.SequenceNumber, err)
+ continue
+ }
+ assert.Equal(p.raw, pkt)
+ }
+ })
+ }
+}
diff --git a/stream_srtcp.go b/stream_srtcp.go
index e335937..3e0b9ac 100644
--- a/stream_srtcp.go
+++ b/stream_srtcp.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/pion/rtcp"
- "github.com/pion/transport/packetio"
+ "github.com/pion/transport/v2/packetio"
)
// Limit the buffer size to 100KB
diff --git a/stream_srtp.go b/stream_srtp.go
index 8b57c7c..284f88e 100644
--- a/stream_srtp.go
+++ b/stream_srtp.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/pion/rtp"
- "github.com/pion/transport/packetio"
+ "github.com/pion/transport/v2/packetio"
)
// Limit the buffer size to 1MB
diff --git a/stream_srtp_test.go b/stream_srtp_test.go
index 9b09118..3888f8a 100644
--- a/stream_srtp_test.go
+++ b/stream_srtp_test.go
@@ -8,7 +8,7 @@ import (
"time"
"github.com/pion/rtp"
- "github.com/pion/transport/packetio"
+ "github.com/pion/transport/v2/packetio"
"github.com/stretchr/testify/assert"
)
@@ -202,7 +202,7 @@ func BenchmarkWriteRTP(b *testing.B) {
b.Run("CTR-100", func(b *testing.B) {
benchmarkWriteRTP(b, profileCTR, 100)
})
- b.Run("CTR-1400", func(b *testing.B) {
+ b.Run("CTR-1000", func(b *testing.B) {
benchmarkWriteRTP(b, profileCTR, 1000)
})
b.Run("GCM-100", func(b *testing.B) {
More details
Historical runs
- missing-go-package: Missing Go package: github.com/pion/transport/v2/utils/xor
- command-failed: Script ['deb-new-upstream', '--snapshot', '--refresh-patches'] failed to run with code 1
- dist-command-failed: Command 'SCHROOT=sid-amd64-sbuild PYTHONPATH=/:/usr/lib/python310.zip:/usr/lib/python3.10:/usr/lib/python3.10/lib-dynload:/usr/local/lib/python3.10/dist-packages:/usr/lib/python3/dist-packages /usr/bin/python3 -m janitor.debian.dist --log-directory=/tmp/janitor-workero1n8prb2 --packaging=/tmp/janitor-workero1n8prb2/golang-github-pion-srtp.git/debian --apt-update --apt-dist-upgrade' returned non-zero exit status 1.
- worker-exception: W:Download is performed unsandboxed as root as file '/tmp/tmpggf1tc0v/var/lib/apt/lists/partial/deb.debian.org_debian_dists_sid_InRelease' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied), W:GPG error: http://deb.debian.org/debian sid InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9, E:Release file for http://deb.debian.org/debian/dists/sid/InRelease is not valid yet (invalid for another 2d 0h 4min 19s). Updates for this repository will not be applied.
- 401-unauthorized: Unexpected HTTP status 401 for https://salsa.debian.org/go-team/packages/golang-github-pion-srtp.git/info/refs?service=git-upload-pack: Unable to handle http code: Unauthorized