MCPcopy Create free account
hub / github.com/SamNet-dev/snix / BuildClientHelloPadded

Function BuildClientHelloPadded

core/injector/clienthello.go:118–158  ·  view source on GitHub ↗

BuildClientHelloPadded returns a ClientHello whose total size is OutputLen + extraPad bytes, where extraPad ∈ [0, 65000]. The extension is byte-identical to BuildClientHello when extraPad == 0. Extra bytes are appended to the padding extension. The record and handshake length fields are recomputed

(rnd, sessID, sni, keyShare []byte, extraPad int)

Source from the content-addressed store, hash-verified

116// a DPI that looked for "exact length 517 during handshake-ACK window"
117// cannot match a variable-length stream.
118func BuildClientHelloPadded(rnd, sessID, sni, keyShare []byte, extraPad int) ([]byte, error) {
119 if extraPad < 0 || extraPad > 65000 {
120 return nil, ErrInvalidInput
121 }
122 base, err := BuildClientHello(rnd, sessID, sni, keyShare)
123 if err != nil {
124 return nil, err
125 }
126 if extraPad == 0 {
127 return base, nil
128 }
129
130 out := make([]byte, 0, len(base)+extraPad)
131 out = append(out, base...)
132 out = append(out, make([]byte, extraPad)...)
133
134 // Fix up the three length fields that covered the inner structures.
135 // Record header bytes 3-4: TLS record body length (handshake data only,
136 // excludes the 5-byte record header itself).
137 recBodyLen := uint16(len(out) - 5)
138 out[3] = byte(recBodyLen >> 8)
139 out[4] = byte(recBodyLen)
140 // Handshake header bytes 6-8: uint24 handshake body length (excludes the
141 // 4-byte handshake header itself).
142 hsBodyLen := len(out) - 9
143 out[6] = byte(hsBodyLen >> 16)
144 out[7] = byte(hsBodyLen >> 8)
145 out[8] = byte(hsBodyLen)
146 // Padding extension is the last extension. Its 2-byte length field sits
147 // immediately after static5 (bytes [len(base)-2-padN : len(base)-padN]).
148 // Simpler: extension length = (old padding size) + extraPad. Old padding
149 // size is at bytes [len(base)-2-oldPad : len(base)-oldPad]. oldPad =
150 // (paddingBudget - len(sni)).
151 oldPad := paddingBudget - len(sni)
152 padLenOff := len(base) - 2 - oldPad
153 newPadBody := oldPad + extraPad
154 out[padLenOff] = byte(newPadBody >> 8)
155 out[padLenOff+1] = byte(newPadBody)
156
157 return out, nil
158}
159
160func mustHex(s string) []byte {
161 b, err := hex.DecodeString(s)

Callers 4

newFakeClientHelloMethod · 0.92

Calls 1

BuildClientHelloFunction · 0.85

Tested by 3