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

Method readClientHello

handshake_server.go:136–214  ·  view source on GitHub ↗

readClientHello reads a ClientHello message and selects the protocol version.

(ctx context.Context)

Source from the content-addressed store, hash-verified

134
135// readClientHello reads a ClientHello message and selects the protocol version.
136func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, *echServerContext, error) {
137 // clientHelloMsg is included in the transcript, but we haven't initialized
138 // it yet. The respective handshake functions will record it themselves.
139 msg, err := c.readHandshake(nil)
140 if err != nil {
141 return nil, nil, err
142 }
143 clientHello, ok := msg.(*clientHelloMsg)
144 if !ok {
145 c.sendAlert(alertUnexpectedMessage)
146 return nil, nil, unexpectedMessageError(clientHello, msg)
147 }
148
149 // ECH processing has to be done before we do any other negotiation based on
150 // the contents of the client hello, since we may swap it out completely.
151 var ech *echServerContext
152 if len(clientHello.encryptedClientHello) != 0 {
153 echKeys := c.config.EncryptedClientHelloKeys
154 if c.config.GetEncryptedClientHelloKeys != nil {
155 echKeys, err = c.config.GetEncryptedClientHelloKeys(clientHelloInfo(ctx, c, clientHello))
156 if err != nil {
157 c.sendAlert(alertInternalError)
158 return nil, nil, err
159 }
160 }
161 clientHello, ech, err = c.processECHClientHello(clientHello, echKeys)
162 if err != nil {
163 return nil, nil, err
164 }
165 }
166
167 var configForClient *Config
168 originalConfig := c.config
169 if c.config.GetConfigForClient != nil {
170 chi := clientHelloInfo(ctx, c, clientHello)
171 if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
172 c.sendAlert(alertInternalError)
173 return nil, nil, err
174 } else if configForClient != nil {
175 c.config = configForClient
176 }
177 }
178 c.ticketKeys = originalConfig.ticketKeys(configForClient)
179
180 clientVersions := clientHello.supportedVersions
181 if clientHello.vers >= VersionTLS13 && len(clientVersions) == 0 {
182 // RFC 8446 4.2.1 indicates when the supported_versions extension is not sent,
183 // compatible servers MUST negotiate TLS 1.2 or earlier if supported, even
184 // if the client legacy version is TLS 1.3 or later.
185 //
186 // Since we reject empty extensionSupportedVersions in the client hello unmarshal
187 // finding the supportedVersions empty indicates the extension was not present.
188 clientVersions = supportedVersionsFromMax(VersionTLS12)
189 } else if len(clientVersions) == 0 {
190 clientVersions = supportedVersionsFromMax(clientHello.vers)
191 }
192 c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
193 if !ok {

Callers 2

serverHandshakeMethod · 0.95
ServerFunction · 0.80

Calls 8

readHandshakeMethod · 0.95
sendAlertMethod · 0.95
processECHClientHelloMethod · 0.95
unexpectedMessageErrorFunction · 0.85
clientHelloInfoFunction · 0.85
supportedVersionsFromMaxFunction · 0.85
ticketKeysMethod · 0.80
mutualVersionMethod · 0.80

Tested by

no test coverage detected