mediamtx/internal/rtmp/handshake/c2s2.go

63 lines
1.1 KiB
Go
Raw Normal View History

2022-06-05 22:07:24 +00:00
package handshake
import (
2022-06-06 12:24:59 +00:00
"bytes"
2022-06-05 22:07:24 +00:00
"crypto/rand"
"encoding/binary"
2022-06-06 12:24:59 +00:00
"fmt"
2022-06-05 22:07:24 +00:00
"io"
)
// C2S2 is a C2 or S2 packet.
type C2S2 struct {
Time uint32
Time2 uint32
Random []byte
2022-06-06 12:24:59 +00:00
Digest []byte
2022-06-05 22:07:24 +00:00
}
// Read reads a C2S2.
2022-06-08 18:47:36 +00:00
func (c *C2S2) Read(r io.Reader) error {
2022-06-05 22:07:24 +00:00
buf := make([]byte, 1536)
_, err := io.ReadFull(r, buf)
if err != nil {
return err
}
2022-06-06 12:24:59 +00:00
// validate signature
gap := len(buf) - 32
digest := hsMakeDigest(c.Digest, buf, gap)
if !bytes.Equal(buf[gap:gap+32], digest) {
return fmt.Errorf("unable to validate C2/S2 signature")
}
2022-06-05 22:07:24 +00:00
c.Time = binary.BigEndian.Uint32(buf)
c.Time2 = binary.BigEndian.Uint32(buf[4:])
c.Random = buf[8:]
return nil
}
// Write writes a C2S2.
2022-06-06 12:24:59 +00:00
func (c C2S2) Write(w io.Writer) error {
2022-06-05 22:07:24 +00:00
buf := make([]byte, 1536)
binary.BigEndian.PutUint32(buf, c.Time)
binary.BigEndian.PutUint32(buf[4:], c.Time2)
if c.Random == nil {
rand.Read(buf[8:])
} else {
copy(buf[8:], c.Random)
}
// signature
2022-06-06 12:24:59 +00:00
if c.Digest != nil {
gap := len(buf) - 32
digest := hsMakeDigest(c.Digest, buf, gap)
copy(buf[gap:], digest)
}
2022-06-05 22:07:24 +00:00
_, err := w.Write(buf)
return err
}