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

Get SNI for OpenSSL #7291

Merged
merged 11 commits into from
Jan 10, 2019
Merged

Get SNI for OpenSSL #7291

merged 11 commits into from
Jan 10, 2019

Conversation

bararchy
Copy link
Contributor

@bararchy bararchy commented Jan 9, 2019

This PR adds the ability to query the SNI string, having this ability is important when needing to decide which certificate to show the connecting client, or, when creating a proxy that should show the relevant certificate for each host.
There are other reasons for having this ability.

Overall this change is minor and have been tested locally.

src/openssl/ssl/server.cr Outdated Show resolved Hide resolved
@asterite
Copy link
Member

asterite commented Jan 9, 2019

Looks good, though in Ruby I think the method is called hostname and there's also hostname=. I know nothing about openssl, but I just found that.

@asterite
Copy link
Member

asterite commented Jan 9, 2019

(note: I might be wrong)

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@asterite the hostname= or sni= should be in the Client part of SSL::Socket as it sets the SNI for the connection.
I wanted to divide those into small manageable PRs because C bindings + OpenSSL is a scary concept and it's better to take in small doses

Copy link
Contributor

@ysbaddaden ysbaddaden left a comment

Choose a reason for hiding this comment

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

I agree with @asterite. Looking at the OpenSSL documentation, the method could be #hostname with documentation stating that it returns the server name indication (SNI), and there could be SSL_set_tlsext_host_name to implement the #hostname= method which is useful on clients.

src/openssl/ssl/server.cr Outdated Show resolved Hide resolved
Copy link
Member

@straight-shoota straight-shoota left a comment

Choose a reason for hiding this comment

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

Could you add a spec for this method, please?

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@straight-shoota regarding specs, sadly can't make those until the client side will be finished, unless you wish me to do an ugly hack like

system("openssl s_client")

etc..

@jhass
Copy link
Member

jhass commented Jan 9, 2019

For which openssl versions are these methods available? Do we need or want to conditionalize defining them for nicer compilation errors?

Btw, maybe I'm wrong, but I vaguely remember that you can bundle up your certs and keys into a single file, load that into a context and openssl will pick the first matching one.

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

Ok, this is really wierd, the function should be present in 1.1.0..master, I can see it here: https://github.com/openssl/openssl/blob/master/apps/s_client.c#L1980
Also here: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_tlsext_host_name.html

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@asterite @jhass @straight-shoota @RX14

I totally missed we already have the hostname ability in the client socket already, so, Added only server side, added specs which should pass.

Let's squash and merge, then I'll start working on adding the callback which is the needed part for the whole SNI server flow

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@asterite @ysbaddaden @straight-shoota can I get another approval ?

src/openssl/ssl/socket.cr Outdated Show resolved Hide resolved
Copy link
Member

@asterite asterite left a comment

Choose a reason for hiding this comment

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

I just left a question, feel free to ignore it if it doesn't make sense.

Copy link
Contributor

@ysbaddaden ysbaddaden left a comment

Choose a reason for hiding this comment

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

Just one last tiny change to use @jhass proposal for the documentation, and it's 👍

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@jhass @ysbaddaden done. Updated docs comment
Feel free to merge or let the CI ran for 50min for a comment hahahah

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@ysbaddaden all green LGTM 🎉

OpenSSL::SSL::Server.open tcp_server, server_context do |server|
spawn do
sleep 1
OpenSSL::SSL::Socket::Client.open(TCPSocket.new(tcp_server.local_address.address, tcp_server.local_address.port), client_context, hostname: "example.com") do |socket|
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please split this line? Its complexity makes it hard to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can, keep in mind its a copy paste of the above tests, I just wanted to keep the same structure, maybe it should be better to merge this PR and make a new one fixing all the examples in the file which use this exact same line?

@bararchy
Copy link
Contributor Author

bararchy commented Jan 9, 2019

@straight-shoota can I get your approval?

Copy link
Member

@straight-shoota straight-shoota left a comment

Choose a reason for hiding this comment

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

I'm not happy about the sleep 1 but I think at this point it's fine to merge and refactor the entire specs file.

Copy link
Member

@sdogruyol sdogruyol left a comment

Choose a reason for hiding this comment

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

Thank you @bararchy 👍

@sdogruyol sdogruyol merged commit 380063a into crystal-lang:master Jan 10, 2019
@sdogruyol sdogruyol added this to the 0.27.1 milestone Jan 10, 2019
urde-graven pushed a commit to urde-graven/crystal that referenced this pull request Jan 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants