processHelloRetryRequest handles the HRR in hs.serverHello, modifies and resends hs.hello, and reads the new ServerHello into hs.serverHello.
()
| 175 | // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and |
| 176 | // resends hs.hello, and reads the new ServerHello into hs.serverHello. |
| 177 | func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { |
| 178 | c := hs.c |
| 179 | |
| 180 | // The first ClientHello gets double-hashed into the transcript upon a |
| 181 | // HelloRetryRequest. (The idea is that the server might offload transcript |
| 182 | // storage to the client in the cookie.) See RFC 8446, Section 4.4.1. |
| 183 | chHash := hs.transcript.Sum(nil) |
| 184 | hs.transcript.Reset() |
| 185 | hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) |
| 186 | hs.transcript.Write(chHash) |
| 187 | hs.transcript.Write(hs.serverHello.marshal()) |
| 188 | |
| 189 | // The only HelloRetryRequest extensions we support are key_share and |
| 190 | // cookie, and clients must abort the handshake if the HRR would not result |
| 191 | // in any change in the ClientHello. |
| 192 | if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil { |
| 193 | c.sendAlert(alertIllegalParameter) |
| 194 | return errors.New("tls: server sent an unnecessary HelloRetryRequest message") |
| 195 | } |
| 196 | |
| 197 | if hs.serverHello.cookie != nil { |
| 198 | hs.hello.cookie = hs.serverHello.cookie |
| 199 | } |
| 200 | |
| 201 | if hs.serverHello.serverShare.group != 0 { |
| 202 | c.sendAlert(alertDecodeError) |
| 203 | return errors.New("tls: received malformed key_share extension") |
| 204 | } |
| 205 | |
| 206 | // If the server sent a key_share extension selecting a group, ensure it's |
| 207 | // a group we advertised but did not send a key share for, and send a key |
| 208 | // share for it this time. |
| 209 | if curveID := hs.serverHello.selectedGroup; curveID != 0 { |
| 210 | curveOK := false |
| 211 | for _, id := range hs.hello.supportedCurves { |
| 212 | if id == curveID { |
| 213 | curveOK = true |
| 214 | break |
| 215 | } |
| 216 | } |
| 217 | if !curveOK { |
| 218 | c.sendAlert(alertIllegalParameter) |
| 219 | return errors.New("tls: server selected unsupported group") |
| 220 | } |
| 221 | if hs.ecdheParams.CurveID() == curveID { |
| 222 | c.sendAlert(alertIllegalParameter) |
| 223 | return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share") |
| 224 | } |
| 225 | if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { |
| 226 | c.sendAlert(alertInternalError) |
| 227 | return errors.New("tls: CurvePreferences includes unsupported curve") |
| 228 | } |
| 229 | params, err := generateECDHEParameters(c.config.rand(), curveID) |
| 230 | if err != nil { |
| 231 | c.sendAlert(alertInternalError) |
| 232 | return err |
| 233 | } |
| 234 | hs.ecdheParams = params |
no test coverage detected