8000 SSL Peer Verification and other SSL improvements by burke · Pull Request #334 · eventmachine/eventmachine · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
< 8000 div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full"> Dismiss alert

SSL Peer Verification and other SSL improvements #334

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

Closed
wants to merge 21 commits into from

Conversation

burke
Copy link
@burke burke commented May 24, 2012

The commit log is quite descriptive, but here are some highlights:

  • Includes @miketheiron's pull Additional options for SSL certificate verification #84: private key passwords and custom CA files.
  • Perform real SSL verification internally:
    • Verify that a cert is signed by a trusted CA
    • If a :hostname argument is passed to start_tls, verify that the Subject CN matches this value.
  • Add a new preverify_ok parameter to ssl_verify_peer:
    • true or false, this indicates whether the C-level certificate verification passed or failed.
    • By default, ssl_verify_peer now returns preverify_ok, ie. the openssl verification result. This is normally the right thing to do: this method no longer requires overriding for security.
    • Overriding methods can choose to ignore preverify_ok and determine validity on their own based on the still-passed cert parameter or any other criteria.
    • C code checks the method arity so existing one-parameter ssl_verify_peer definitions will continue to work with no modifications.
  • Bundled a default CA file, used if no :ca_file is passed to start_tls.
  • Updated docs and tests.

Very open to discussion on this. Feel free to hit me up on email or gtalk at burke@burkelibbey.org.

Mike Hinshelwood and others added 17 commits June 1, 2010 11:01
This will enable ruby to optionally override ssl_verify_peer to
change the result, or to leave it and accept whatever OpenSSL
decided. This will be more useful once EM is modified to accept
real certificated and CAs, and it can intelligently determine this
itself.
…ls to OpenSSL

Conflicts:
	lib/em/connection.rb
This extracts an error-handling routine repeated 5 times into an
inline function.
This is mostly a no-op, with two notable exceptions:

1) Before, a private key password would never be set unless a private
   key was also supplied. Now it will be. This should never really have
   any noticeable effect.

2) ca_file previously had no effect when supplied to a client
   connection. Now it works on either client or server.
This reduces the use of global variables a bit, and moves certs into
a new directory called "certs".

This also adds some certs for a test CA and a client signed by it.
These will be used in soon-to-be-written tests.
This is now consistent with the existing file parameters to start_tls.
This hostname is passed in as a :hostname option to start_tls.
It's stored on the SslBox_t, using ex_data.

I'm not 100% using sk_X509_shift is the best way to go about
getting the correct certificate to check against, but it seems to work
in my test cases.

I will shortly rewrite these test cases to not hit the network.
1) Raise an error if called with unsupported arguments
2) Default ca_file to the mozilla default CA file
@burke
Copy link
Author
burke commented May 24, 2012

One thing I would still like to add at some point is a message indicating to ruby why C-level verification failed. I haven't decided quite how to implement that yet.

One potential option would be to add a third parameter to ssl_verify_peer, so that the signature becomes (cert, preverify_ok, preverify_status), where preverify_status is something like {{X509_STORE_get_error(ctx)}}:{{X509_verify_cert_error_string(err)}}, eg. "0:ok", etc. Or it could be split into a numeric status and an error string. Or preverify_ok could just be the status and the default method could compare it to 0.

I'll think about this some more and do that in the future, but I don't think it should be a blocker for this pull request.

Burke Libbey added 4 commits May 28, 2012 13:13
If a server is using SNI, we need to add the hostname to the client SSL
connection.
Previously, the code did not take into account subjectAltName
extensions, multiple CN attributes, or wildcard domains.
@ibc
Copy link
Contributor
ibc commented Aug 28, 2012

HI, about:

If a :hostname argument is passed to start_tls, verify that the Subject CN matches this value.

That is a limitation. TLS certificates can include subjectAltName fields which take preference over the Subject CN, and there are protocol-dependant rules to inspect the value of those subjectAltName fields, so I don't think it's a good idea.

For example check http://tools.ietf.org/html/rfc5922.

@burke
Copy link
8000
Author
burke commented Aug 31, 2012

I didn't implement any protocol-dependent rules, but I do check the subjectAltName:

https://github.com/burke/eventmachine/blob/ba6058cf7db069ba39072462ba1c1ff8e6005701/ext/ssl.cpp#L440-446

Hostname verification seemed like an important feature, and it can trivially be skipped by not passing a hostname. I realize it's not perfect.

@ibc
Copy link
Contributor
ibc commented Sep 1, 2012

Hi @burke, please check my TLS inspection code in OverSIP (a SIP proxy on top of EM):

https://github.com/versatica/OverSIP/blob/master/lib/oversip/tls.rb#L130

The method get_sip_identities(cert) receives as parameter an OpenSSL::X509::Certificate instance created with the PEM string retrieved during EM TLS handshake.

@jtulley
Copy link
jtulley commented Nov 7, 2012

I've got a change set prepared which does almost exactly this. I should've looked here first. :) One big difference with mine, is that I allow you to pass in a full ca-cert file (not a cert chain, which is limited), and / or a capath. So, in this regard it is rather like libcurl or command-line curl. No bundling of certs.

Then, I pass to ssl_verify_peer the pem(as usual), an error code (with "0" / X509_V_OK for succes), and a certificate depth, which is useful for the method to know when to do a domain name match. Then it is completely up to ssl_verify_peer to do the domain name match. I like yours because it is less likely that an implementer will miss that crucial step (as is common with OpenSSL-based implementations).

I'll still submit mine, and I'm not at all clued into the EM community (if there is one), so I'm not sure how easy it is to get something into the code. Definitely this is a big hole in the current code that needs to be filled by your or my changes.

@jtulley
Copy link
jtulley commented Nov 7, 2012

I'm proposing that we merge this change with mine, keeping the internal host name validation (is using ruby's OpenSSL library, OpenSSL::SSL.verify_certificate_identity sufficient?) of this pull request, getting rid of the bundled certs (this is a big maintenance issue), and instead opting for my method of allowing you to specify a ca cert path, or a ca-cert file that has multiple (not chained, necessarily) certificates. Also, I'd like to keep the augmented ssl_verify_peer method, so that the ruby code has some context when adding on additional certificate validation through that method.

@ibc
Copy link
Contributor
ibc commented Nov 7, 2012

Copy&paste of the same comment writen in #378:

@jtulley, as I described here and here, the world is bigger than just HTTP. Comparing the certificate Common Name with a given domain is NOT enough in many cases, so please don't try to include such a limited and incorrect comparison at core level since it's the application layer the only that can decide how the certificate must be inspected for validating anything related to the underlying application protocol.

@burke burke closed this Mar 20, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0