Go version
Any
Output of go env
in your module/workspace:
GOARCH="amd64"
What did you do?
Set up a HTTPS server using crypto/tls and intiate a TLS handshake with it where the TLS Client Hello contains the extension "server_name". A complete example for this has already been provided in #16072. This issue is therefore a duplicate of #16072 because we believe that the decision taken there should be revisited for the reasons given below.
What did you see happen?
The TLS Server Hello response of the HTTPS server does not contain a server_name extension.
What did you expect to see?
RFC 6066 section 3 mandates that a server MAY use the information from the server_name extension in the Client Hello. However if it does so, then the server MUST in turn include the extension in the response with an empty value:
A server that receives a client hello containing the "server_name" extension MAY use the information contained in the extension to guide its selection of an appropriate certificate to return to the client, and/or other aspects of security policy. In this event, the server SHALL include an extension of type "server_name" in the (extended) server hello. The "extension_data" field of this extension SHALL be empty. (the word SHALL in RFCs is a synonym for MUST, see RFC 2119)
Currently software using GOs crypto/tls stack does never sent a server_name extension. This is not just a theoretical issue, but creates actual compatibility problems: If you turn the statement from RFC 6066 around, it means that a server which receives a server_name extension from the client but does not include the extension in its response, does not use the server_name information from the client, ie it does not use SNI. Some software from eg IBM, Citrix or AWS will then omit the server_name extension from following requests to the same server, because it knows that the server doesn't need it. However if the GO server is actually using SNI (without telling it), those requests will fail.
To fix this, crypto/tls should always include an empty server_name extension if the client sent this extension. I cannot think of a scenario where this causes a problem. Even if the server does not use SNI no harm is done if the client believes otherwise and continues to supply a superfluous server_name extension.
Comment From: gabyhelp
Related Issues
- crypto/tls: server should send empty server_name extension when using SNI #16072 (closed)
- crypto/tls: Go HTTP server - when receiving Client Hello with SNI - is not including Server Name extension in Server Hello #54691 (closed)
- proposal: crypto/tls: make server name extension optional #28754 (closed)
- crypto/tls: Conn.ConnectionState should set state.ServerName from c.serverName unconditionally - handshakeComplete is not necessary for SNI #15571 (closed)
- crypto/tls: GetCertificate should have a way to signal `unrecognized_name` #19300 (closed)
- crypto/tls: abort handshake if unrequested extensions are sent #51090
- crypto/tls: Allow sending unrecognized_name alert from GetCertificate #18377 (closed)
Related Discussions
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: seankhliao
note the RFC only says SHALL, not MUST. I think we need to see real examples of failures.
Comment From: AGWA
@seankhliao SHALL means the same thing as MUST, see RFC 2119