readClientHello reads a ClientHello message and selects the protocol version.
(ctx context.Context)
| 134 | |
| 135 | // readClientHello reads a ClientHello message and selects the protocol version. |
| 136 | func (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 { |
no test coverage detected