Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ESNI client and server support #172

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Add ESNI client and server support #172

wants to merge 2 commits into from

Conversation

Lekensteyn
Copy link
Contributor

@Lekensteyn Lekensteyn commented May 2, 2019

Implements https://tools.ietf.org/html/draft-ietf-tls-esni-01
Extends the tls.Config API with a ClientESNIKeys structure which must
contain a valid key. If this key is not valid, the handshake will fail.
A GetServerESNIKeys API is also added which allows the server to
dynamically query for an appropriate ESNI key.

Add a new 'esnitool' utility to generate ESNIKeys for testing purposes,
this uses a short lifetime, a single curve and cipher suite. The test
client and server can now be used with these keys. Additionally the test
client can securely query the ESNI key from DNS (hardcoded to use
1.1.1.1:853 using DoT for now).


Fixes #138

This change depends on #171 to ensure that the shared secret can be calculated without access to a tls.Conn structure. Therefore that commit is also included in this PR.

Note: this does not implement the latest draft (-03). If so, at least these changes are necessary:

  • Use new ESNIKeys.public_name in the SNI extension (and change the version number accordingly).
  • Distinguish "ESNI PSK"s and "non-ESNI PSK"s and forbid mixing them with Client Hellos.

_dev/Makefile Outdated Show resolved Hide resolved
The Docker image is based on Linux, be sure to build a binary that is
compatible with it. Fixes interop tests on macOS. During development,
one can use: `cd _dev/tris-testclient && ../go.sh build -v -i .`
@Lekensteyn
Copy link
Contributor Author

I've addressed the review comments, the GOOS=linux change was split in a separate commit. Since it the ESNI changes touch the same context, the ESNI patch effectively depends on that.

Aside from these two patches, there is also a Makefile patch to avoid unnecessary rebuilds. This is independent of ESNI, but included here for easier testing. I hope that PR #173 can be merged first. If it makes it easier for you, I could also drop that rebuild patch here and restrict PR #173 to that single change. Let me know!

Implements https://tools.ietf.org/html/draft-ietf-tls-esni-01
Extends the tls.Config API with a ClientESNIKeys structure which must
contain a valid key. If this key is not valid, the handshake will fail.
A GetServerESNIKeys API is also added which allows the server to
dynamically query for an appropriate ESNI key.

Add a new 'esnitool' utility to generate ESNIKeys for testing purposes,
this uses a short lifetime, a single curve and cipher suite. The test
client and server can now be used with these keys. Additionally the test
client can securely query the ESNI key from DNS (hardcoded to use
1.1.1.1:853 using DoT for now).
@Lekensteyn
Copy link
Contributor Author

Ended up dropping the rebuild patch since it is not ready, will move that to PR #173. Now this patch is fully independent again and can be reviewed/merged independently.

@kriskwiatkowski
Copy link
Contributor

kriskwiatkowski commented May 7, 2019

Can you improve tests?
At least handshake_messages_test.go, handshake_server_test.go and handshake_client_test.go should be augmented with some testing.
Ideally some test cases are introduced to testdata.

"golang.org/x/crypto/curve25519"
)

// Internal definitions, copied from common.go and esni.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it make sense to have esni.go export them or equivalents?

// nil, then SNI encryption is not enabled.
//
// See https://tools.ietf.org/html/draft-ietf-tls-esni-01
ClientESNIKeys *ESNIKeys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't fit the pattern of a config being reused across connections since the ESNI keys are server specific. I can't think of a great way to do it, but one way would be to have a flag here to enable support, then DialWithDialer would use the resolver passed in to look up the text record.

@@ -674,7 +674,7 @@ func TestCloneNonFuncFields(t *testing.T) {
switch fn := typ.Field(i).Name; fn {
case "Rand":
f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate", "GetDelegatedCredential":
case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "GetClientCertificate", "GetDelegatedCredential", "ClientESNIKeys", "GetServerESNIKeys":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClientESNIKeys isn't a function

@eighthave
Copy link

I'm working with a group, https://defo.ie/ on the ESNI standard. There are some test servers there that might be useful. Also, there are some tests in our openssl fork: https://github.com/sftcd/openssl

We also have working versions of nginx and lighttpd, and are building automated test suites to run in Travis CI and GitLab CI.

@mvdan
Copy link
Contributor

mvdan commented Nov 5, 2019

@Lekensteyn perhaps it would be a good idea to switch to a patch on top of the upcoming Go 1.14.x. It seems to contain all non-draft TLS 1.3 features, and it would smooth the way towards eventually incorporating it into upstream Go. I also imagine that it's best to get the latest fixes from upstream's crypto packages.

@Lekensteyn
Copy link
Contributor Author

@mvdan The plan to rebase has been an unwritten one, I have now opened #184 to track it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support ESNI
5 participants