MCPcopy
hub / github.com/XTLS/REALITY / processHelloRetryRequest

Method processHelloRetryRequest

handshake_client_tls13.go:235–414  ·  view source on GitHub ↗

processHelloRetryRequest handles the HRR in hs.serverHello, modifies and resends hs.hello, and reads the new ServerHello into hs.serverHello.

()

Source from the content-addressed store, hash-verified

233// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
234// resends hs.hello, and reads the new ServerHello into hs.serverHello.
235func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
236 c := hs.c
237
238 // The first ClientHello gets double-hashed into the transcript upon a
239 // HelloRetryRequest. (The idea is that the server might offload transcript
240 // storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
241 chHash := hs.transcript.Sum(nil)
242 hs.transcript.Reset()
243 hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
244 hs.transcript.Write(chHash)
245 if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
246 return err
247 }
248
249 var isInnerHello bool
250 hello := hs.hello
251 if hs.echContext != nil {
252 chHash = hs.echContext.innerTranscript.Sum(nil)
253 hs.echContext.innerTranscript.Reset()
254 hs.echContext.innerTranscript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
255 hs.echContext.innerTranscript.Write(chHash)
256
257 if hs.serverHello.encryptedClientHello != nil {
258 if len(hs.serverHello.encryptedClientHello) != 8 {
259 hs.c.sendAlert(alertDecodeError)
260 return errors.New("tls: malformed encrypted client hello extension")
261 }
262
263 confTranscript := cloneHash(hs.echContext.innerTranscript, hs.suite.hash)
264 hrrHello := make([]byte, len(hs.serverHello.original))
265 copy(hrrHello, hs.serverHello.original)
266 hrrHello = bytes.Replace(hrrHello, hs.serverHello.encryptedClientHello, make([]byte, 8), 1)
267 confTranscript.Write(hrrHello)
268 h := hs.suite.hash.New
269 prk, err := hkdf.Extract(h, hs.echContext.innerHello.random, nil)
270 if err != nil {
271 c.sendAlert(alertInternalError)
272 return err
273 }
274 acceptConfirmation := tls13.ExpandLabel(h, prk, "hrr ech accept confirmation", confTranscript.Sum(nil), 8)
275 if subtle.ConstantTimeCompare(acceptConfirmation, hs.serverHello.encryptedClientHello) == 1 {
276 hello = hs.echContext.innerHello
277 c.serverName = c.config.ServerName
278 isInnerHello = true
279 c.echAccepted = true
280 }
281 }
282
283 if err := transcriptMsg(hs.serverHello, hs.echContext.innerTranscript); err != nil {
284 return err
285 }
286 } else if hs.serverHello.encryptedClientHello != nil {
287 // Unsolicited ECH extension should be rejected
288 c.sendAlert(alertUnsupportedExtension)
289 return errors.New("tls: unexpected encrypted client hello extension in serverHello")
290 }
291
292 // The only HelloRetryRequest extensions we support are key_share and

Callers 1

handshakeMethod · 0.95

Calls 15

checkServerHelloOrHRRMethod · 0.95
ExpandLabelFunction · 0.92
transcriptMsgFunction · 0.85
cloneHashFunction · 0.85
curveForCurveIDFunction · 0.85
generateECDHEKeyFunction · 0.85
cipherSuiteTLS13ByIDFunction · 0.85
computeAndUpdatePSKFunction · 0.85
unexpectedMessageErrorFunction · 0.85
ResetMethod · 0.80
sendAlertMethod · 0.80

Tested by

no test coverage detected