github.com/tumi8/quic-go@v0.37.4-tum/fuzzing/tokens/fuzz.go (about) 1 package tokens 2 3 import ( 4 "encoding/binary" 5 "math/rand" 6 "net" 7 "time" 8 9 "github.com/tumi8/quic-go/noninternal/handshake" 10 "github.com/tumi8/quic-go/noninternal/protocol" 11 ) 12 13 func Fuzz(data []byte) int { 14 if len(data) < 8 { 15 return -1 16 } 17 seed := binary.BigEndian.Uint64(data[:8]) 18 data = data[8:] 19 tg, err := handshake.NewTokenGenerator(rand.New(rand.NewSource(int64(seed)))) 20 if err != nil { 21 panic(err) 22 } 23 if len(data) < 1 { 24 return -1 25 } 26 s := data[0] % 3 27 data = data[1:] 28 switch s { 29 case 0: 30 tg.DecodeToken(data) 31 return 1 32 case 1: 33 return newToken(tg, data) 34 case 2: 35 return newRetryToken(tg, data) 36 } 37 return -1 38 } 39 40 func newToken(tg *handshake.TokenGenerator, data []byte) int { 41 if len(data) < 1 { 42 return -1 43 } 44 usesUDPAddr := data[0]%2 == 0 45 data = data[1:] 46 if len(data) != 18 { 47 return -1 48 } 49 var addr net.Addr 50 if usesUDPAddr { 51 addr = &net.UDPAddr{ 52 Port: int(binary.BigEndian.Uint16(data[:2])), 53 IP: net.IP(data[2:]), 54 } 55 } else { 56 addr = &net.TCPAddr{ 57 Port: int(binary.BigEndian.Uint16(data[:2])), 58 IP: net.IP(data[2:]), 59 } 60 } 61 start := time.Now() 62 encrypted, err := tg.NewToken(addr) 63 if err != nil { 64 panic(err) 65 } 66 token, err := tg.DecodeToken(encrypted) 67 if err != nil { 68 panic(err) 69 } 70 if token.IsRetryToken { 71 panic("didn't encode a Retry token") 72 } 73 if token.SentTime.Before(start) || token.SentTime.After(time.Now()) { 74 panic("incorrect send time") 75 } 76 if token.OriginalDestConnectionID.Len() > 0 || token.RetrySrcConnectionID.Len() > 0 { 77 panic("didn't expect connection IDs") 78 } 79 return 1 80 } 81 82 func newRetryToken(tg *handshake.TokenGenerator, data []byte) int { 83 if len(data) < 2 { 84 return -1 85 } 86 origDestConnIDLen := int(data[0] % 21) 87 retrySrcConnIDLen := int(data[1] % 21) 88 data = data[2:] 89 if len(data) < origDestConnIDLen { 90 return -1 91 } 92 origDestConnID := protocol.ParseConnectionID(data[:origDestConnIDLen]) 93 data = data[origDestConnIDLen:] 94 if len(data) < retrySrcConnIDLen { 95 return -1 96 } 97 retrySrcConnID := protocol.ParseConnectionID(data[:retrySrcConnIDLen]) 98 data = data[retrySrcConnIDLen:] 99 100 if len(data) < 1 { 101 return -1 102 } 103 usesUDPAddr := data[0]%2 == 0 104 data = data[1:] 105 if len(data) != 18 { 106 return -1 107 } 108 start := time.Now() 109 var addr net.Addr 110 if usesUDPAddr { 111 addr = &net.UDPAddr{ 112 Port: int(binary.BigEndian.Uint16(data[:2])), 113 IP: net.IP(data[2:]), 114 } 115 } else { 116 addr = &net.TCPAddr{ 117 Port: int(binary.BigEndian.Uint16(data[:2])), 118 IP: net.IP(data[2:]), 119 } 120 } 121 encrypted, err := tg.NewRetryToken(addr, origDestConnID, retrySrcConnID) 122 if err != nil { 123 panic(err) 124 } 125 token, err := tg.DecodeToken(encrypted) 126 if err != nil { 127 panic(err) 128 } 129 if !token.IsRetryToken { 130 panic("expected a Retry token") 131 } 132 if token.SentTime.Before(start) || token.SentTime.After(time.Now()) { 133 panic("incorrect send time") 134 } 135 if token.OriginalDestConnectionID != origDestConnID { 136 panic("orig dest conn ID doesn't match") 137 } 138 if token.RetrySrcConnectionID != retrySrcConnID { 139 panic("retry src conn ID doesn't match") 140 } 141 return 1 142 }