return an error in case the random number generator fails (#2120)
This commit is contained in:
parent
dfc8e1fa91
commit
b42154fa6a
|
@ -177,9 +177,8 @@ func TestConfEncryption(t *testing.T) {
|
|||
copy(secretKey[:], key)
|
||||
|
||||
var nonce [24]byte
|
||||
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err := io.ReadFull(rand.Reader, nonce[:])
|
||||
require.NoError(t, err)
|
||||
|
||||
encrypted := secretbox.Seal(nonce[:], []byte(plaintext), &nonce, &secretKey)
|
||||
return base64.StdEncoding.EncodeToString(encrypted)
|
||||
|
|
|
@ -160,7 +160,7 @@ func marshalICEFragment(offer *webrtc.SessionDescription, candidates []*webrtc.I
|
|||
|
||||
type webRTCHTTPServerParent interface {
|
||||
logger.Writer
|
||||
generateICEServers() []webrtc.ICEServer
|
||||
generateICEServers() ([]webrtc.ICEServer, error)
|
||||
sessionNew(req webRTCSessionNewReq) webRTCSessionNewRes
|
||||
sessionAddCandidates(req webRTCSessionAddCandidatesReq) webRTCSessionAddCandidatesRes
|
||||
}
|
||||
|
@ -346,9 +346,15 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
|
|||
case "whip", "whep":
|
||||
switch ctx.Request.Method {
|
||||
case http.MethodOptions:
|
||||
servers, err := s.parent.generateICEServers()
|
||||
if err != nil {
|
||||
ctx.Writer.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PATCH")
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type, If-Match")
|
||||
ctx.Writer.Header()["Link"] = iceServersToLinkHeader(s.parent.generateICEServers())
|
||||
ctx.Writer.Header()["Link"] = iceServersToLinkHeader(servers)
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
|
||||
case http.MethodPost:
|
||||
|
@ -376,12 +382,18 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
servers, err := s.parent.generateICEServers()
|
||||
if err != nil {
|
||||
ctx.Writer.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writer.Header().Set("Content-Type", "application/sdp")
|
||||
ctx.Writer.Header().Set("Access-Control-Expose-Headers", "E-Tag, Accept-Patch, Link")
|
||||
ctx.Writer.Header().Set("E-Tag", res.sx.secret.String())
|
||||
ctx.Writer.Header().Set("ID", res.sx.uuid.String())
|
||||
ctx.Writer.Header().Set("Accept-Patch", "application/trickle-ice-sdpfrag")
|
||||
ctx.Writer.Header()["Link"] = iceServersToLinkHeader(s.parent.generateICEServers())
|
||||
ctx.Writer.Header()["Link"] = iceServersToLinkHeader(servers)
|
||||
ctx.Writer.Header().Set("Location", ctx.Request.URL.String())
|
||||
ctx.Writer.WriteHeader(http.StatusCreated)
|
||||
ctx.Writer.Write(res.answer)
|
||||
|
|
|
@ -31,33 +31,57 @@ const (
|
|||
webrtcTurnSecretExpiration = 24 * 3600 * time.Second
|
||||
)
|
||||
|
||||
func randInt63() int64 {
|
||||
func randInt63() (int64, error) {
|
||||
var b [8]byte
|
||||
rand.Read(b[:])
|
||||
_, err := rand.Read(b[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int64(uint64(b[0]&0b01111111)<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 |
|
||||
uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7]))
|
||||
uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7])), nil
|
||||
}
|
||||
|
||||
// https://cs.opensource.google/go/go/+/refs/tags/go1.20.4:src/math/rand/rand.go;l=119
|
||||
func randInt63n(n int64) int64 {
|
||||
func randInt63n(n int64) (int64, error) {
|
||||
if n&(n-1) == 0 { // n is power of two, can mask
|
||||
return randInt63() & (n - 1)
|
||||
r, err := randInt63()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return r & (n - 1), nil
|
||||
}
|
||||
|
||||
max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
|
||||
v := randInt63()
|
||||
for v > max {
|
||||
v = randInt63()
|
||||
|
||||
v, err := randInt63()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v % n
|
||||
|
||||
for v > max {
|
||||
v, err = randInt63()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return v % n, nil
|
||||
}
|
||||
|
||||
func randomTurnUser() string {
|
||||
func randomTurnUser() (string, error) {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyz1234567890"
|
||||
b := make([]byte, 20)
|
||||
for i := range b {
|
||||
b[i] = charset[int(randInt63n(int64(len(charset))))]
|
||||
j, err := randInt63n(int64(len(charset)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b[i] = charset[int(j)]
|
||||
}
|
||||
return string(b)
|
||||
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
type webRTCManagerAPISessionsListRes struct {
|
||||
|
@ -363,14 +387,23 @@ func (m *webRTCManager) findSessionByUUID(uuid uuid.UUID) *webRTCSession {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *webRTCManager) generateICEServers() []webrtc.ICEServer {
|
||||
func (m *webRTCManager) generateICEServers() ([]webrtc.ICEServer, error) {
|
||||
ret := make([]webrtc.ICEServer, len(m.iceServers))
|
||||
|
||||
for i, server := range m.iceServers {
|
||||
if server.Username == "AUTH_SECRET" {
|
||||
expireDate := time.Now().Add(webrtcTurnSecretExpiration).Unix()
|
||||
server.Username = strconv.FormatInt(expireDate, 10) + ":" + randomTurnUser()
|
||||
|
||||
user, err := randomTurnUser()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
server.Username = strconv.FormatInt(expireDate, 10) + ":" + user
|
||||
|
||||
h := hmac.New(sha1.New, []byte(server.Password))
|
||||
h.Write([]byte(server.Username))
|
||||
|
||||
server.Password = base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
|
@ -380,7 +413,8 @@ func (m *webRTCManager) generateICEServers() []webrtc.ICEServer {
|
|||
Credential: server.Password,
|
||||
}
|
||||
}
|
||||
return ret
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// sessionNew is called by webRTCHTTPServer.
|
||||
|
|
|
@ -274,8 +274,13 @@ func (s *webRTCSession) runPublish() (int, error) {
|
|||
|
||||
defer res.path.publisherRemove(pathPublisherRemoveReq{author: s})
|
||||
|
||||
servers, err := s.parent.generateICEServers()
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
pc, err := newPeerConnection(
|
||||
s.parent.generateICEServers(),
|
||||
servers,
|
||||
s.iceHostNAT1To1IPs,
|
||||
s.iceUDPMux,
|
||||
s.iceTCPMux,
|
||||
|
@ -446,8 +451,13 @@ func (s *webRTCSession) runRead() (int, error) {
|
|||
return http.StatusBadRequest, err
|
||||
}
|
||||
|
||||
servers, err := s.parent.generateICEServers()
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
pc, err := newPeerConnection(
|
||||
s.parent.generateICEServers(),
|
||||
servers,
|
||||
s.iceHostNAT1To1IPs,
|
||||
s.iceUDPMux,
|
||||
s.iceTCPMux,
|
||||
|
|
|
@ -119,7 +119,10 @@ func (c *C1S1) Write(w io.Writer, isC1 bool) error {
|
|||
copy(buf[4:], []byte{0, 0, 0, 0})
|
||||
|
||||
if c.Random == nil {
|
||||
rand.Read(buf[8:])
|
||||
_, err := rand.Read(buf[8:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Random = buf[8:]
|
||||
} else {
|
||||
copy(buf[8:], c.Random)
|
||||
|
|
|
@ -63,7 +63,8 @@ func TestHandshakeFallback(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
c1 := make([]byte, 1536)
|
||||
rand.Read(c1[8:])
|
||||
_, err = rand.Read(c1[8:])
|
||||
require.NoError(t, err)
|
||||
_, err = conn.Write(c1)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
Loading…
Reference in New Issue