mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-01 19:27:35 +03:00
140 lines
2.9 KiB
Go
140 lines
2.9 KiB
Go
package tokens
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/refraction-networking/uquic"
|
|
"github.com/refraction-networking/uquic/internal/handshake"
|
|
"github.com/refraction-networking/uquic/internal/protocol"
|
|
)
|
|
|
|
func Fuzz(data []byte) int {
|
|
if len(data) < 32 {
|
|
return -1
|
|
}
|
|
var key quic.TokenGeneratorKey
|
|
copy(key[:], data[:32])
|
|
data = data[32:]
|
|
tg := handshake.NewTokenGenerator(key)
|
|
if len(data) < 1 {
|
|
return -1
|
|
}
|
|
s := data[0] % 3
|
|
data = data[1:]
|
|
switch s {
|
|
case 0:
|
|
tg.DecodeToken(data)
|
|
return 1
|
|
case 1:
|
|
return newToken(tg, data)
|
|
case 2:
|
|
return newRetryToken(tg, data)
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func newToken(tg *handshake.TokenGenerator, data []byte) int {
|
|
if len(data) < 1 {
|
|
return -1
|
|
}
|
|
usesUDPAddr := data[0]%2 == 0
|
|
data = data[1:]
|
|
if len(data) != 18 {
|
|
return -1
|
|
}
|
|
var addr net.Addr
|
|
if usesUDPAddr {
|
|
addr = &net.UDPAddr{
|
|
Port: int(binary.BigEndian.Uint16(data[:2])),
|
|
IP: net.IP(data[2:]),
|
|
}
|
|
} else {
|
|
addr = &net.TCPAddr{
|
|
Port: int(binary.BigEndian.Uint16(data[:2])),
|
|
IP: net.IP(data[2:]),
|
|
}
|
|
}
|
|
start := time.Now()
|
|
encrypted, err := tg.NewToken(addr)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
token, err := tg.DecodeToken(encrypted)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if token.IsRetryToken {
|
|
panic("didn't encode a Retry token")
|
|
}
|
|
if token.SentTime.Before(start) || token.SentTime.After(time.Now()) {
|
|
panic("incorrect send time")
|
|
}
|
|
if token.OriginalDestConnectionID.Len() > 0 || token.RetrySrcConnectionID.Len() > 0 {
|
|
panic("didn't expect connection IDs")
|
|
}
|
|
return 1
|
|
}
|
|
|
|
func newRetryToken(tg *handshake.TokenGenerator, data []byte) int {
|
|
if len(data) < 2 {
|
|
return -1
|
|
}
|
|
origDestConnIDLen := int(data[0] % 21)
|
|
retrySrcConnIDLen := int(data[1] % 21)
|
|
data = data[2:]
|
|
if len(data) < origDestConnIDLen {
|
|
return -1
|
|
}
|
|
origDestConnID := protocol.ParseConnectionID(data[:origDestConnIDLen])
|
|
data = data[origDestConnIDLen:]
|
|
if len(data) < retrySrcConnIDLen {
|
|
return -1
|
|
}
|
|
retrySrcConnID := protocol.ParseConnectionID(data[:retrySrcConnIDLen])
|
|
data = data[retrySrcConnIDLen:]
|
|
|
|
if len(data) < 1 {
|
|
return -1
|
|
}
|
|
usesUDPAddr := data[0]%2 == 0
|
|
data = data[1:]
|
|
if len(data) != 18 {
|
|
return -1
|
|
}
|
|
start := time.Now()
|
|
var addr net.Addr
|
|
if usesUDPAddr {
|
|
addr = &net.UDPAddr{
|
|
Port: int(binary.BigEndian.Uint16(data[:2])),
|
|
IP: net.IP(data[2:]),
|
|
}
|
|
} else {
|
|
addr = &net.TCPAddr{
|
|
Port: int(binary.BigEndian.Uint16(data[:2])),
|
|
IP: net.IP(data[2:]),
|
|
}
|
|
}
|
|
encrypted, err := tg.NewRetryToken(addr, origDestConnID, retrySrcConnID)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
token, err := tg.DecodeToken(encrypted)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if !token.IsRetryToken {
|
|
panic("expected a Retry token")
|
|
}
|
|
if token.SentTime.Before(start) || token.SentTime.After(time.Now()) {
|
|
panic("incorrect send time")
|
|
}
|
|
if token.OriginalDestConnectionID != origDestConnID {
|
|
panic("orig dest conn ID doesn't match")
|
|
}
|
|
if token.RetrySrcConnectionID != retrySrcConnID {
|
|
panic("retry src conn ID doesn't match")
|
|
}
|
|
return 1
|
|
}
|